【问题标题】:Is bucket a single memory location or similar to an array of memory locations?存储桶是单个内存位置还是类似于内存位置数组?
【发布时间】:2017-04-18 10:13:43
【问题描述】:

正如我们所说,对于2个具有相同哈希码的不相等对象,这些对象存储在同一个桶中,这实际上意味着什么?

【问题讨论】:

  • 完全取决于实现,但通常一个桶是一个链表,包含所有散列到同一个桶的对象。
  • 对于 Java 8 中的标准库容器 java.util.HashMap(和使用 HashMap,但不是 HashtableHashSet)以链表开头,但如果 bucket 超过 8它被更改为平衡树

标签: java hashtable equals hashcode


【解决方案1】:

2 个不相等的对象具有相同的哈希码,对象存储在 同一个桶,具体是什么意思?

我将通过以下Product 类示例向您解释这个概念:

产品类别:

public class Product {

     private int id;

     public Product(int id) {
        this.id = id;
     }

     //add getters and settes for id

     public boolean equals(Object obj) {
         Product product = (Product)obj;
         if(id == product.getId()) {
             return true;
         }
         return false;
     }

     public int hashcode() {
         return 1;
     }
}

测试类:

public class Test {

    public static void main(String[] args) {
        Set<Product> set = new HashSet<>();
        Product p1 = new Product(1);
        Product p2 = new Product(2);
        set.add(p1);
        set.add(p2);
    }
}

假设您为Product 类创建了两个对象p1p2,并添加到HashSet,如上所示。

根据 Product 类的约定,p1p2 对象不相等,因为它们的产品 ID 不同。 在HashSet 内部,这些p1p2 对象根据Product 对象返回的hashcode 存储到不同的桶中(简单地放置不同的内存位置)。 因为您的p1p2 对象都返回相同的哈希码(来自Product 类的hashcode() 方法),所以它们都将保存到同一个存储桶(内存位置)中。 同样,您的所有product 对象(即使product 对象不相等)将被推送到同一个存储桶,因为它们的哈希码相同。

因此,当您尝试使用 set.contains()HashSet 中搜索 product 对象时,必须从整个产品中扫描并找到该对象(假设您已存储 10000 个对象)。

但是当你正确实现你的hashcode(),即为不相等的Product对象返回不同的哈希码,那么product对象将分布在不同的桶中并且检索变得更快(无需扫描所有对象)即显着提高性能。

同样的概念适用于Java中所有Hash*相关的集合API(HashMap、HashSet等)方法。

bucket 是单个内存位置还是类似于内存数组 地点?

一个Bucket存储多个对象引用,每个Hash Bucket内部使用LinkedListTreeMap等数据结构来定位存储的对象。

您可以在此处查看有关同一主题的更多详细信息。

【讨论】:

    【解决方案2】:

    当多个对象落入同一个存储桶时,它们将作为单链表存储在该存储桶中。

    哈希表的优点是您可以在 O(1) 时间内计算出密钥进入哪个存储桶。这意味着,如果每个存储桶只有一个元素,则无论表中有多少元素,您的查找时间都保持不变。当您在一个存储桶中有多个密钥时,如果不检查每个密钥,您将无法判断您在寻找哪一个。当你有一个糟糕的散列函数将许多元素放入同一个桶中时,你就会失去散列表的优势,它开始表现得更像一个链表。

    【讨论】:

      猜你喜欢
      • 2018-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-17
      • 2019-08-15
      • 1970-01-01
      • 2021-01-17
      • 2010-12-26
      相关资源
      最近更新 更多