java - 哪些因素决定新元素能否通过 HashSet 的添加?

标签 java data-structures hashset

我想知道在向 HashSet 添加新元素(对象)之前检查哪些因素(1、2 或 3?)?

如果 HashSet 中存在唯一元素(对象),并且我们尝试添加新对象,则该集合是否仅比较哈希码或使用 equals() 的引用或两者?

  1. HashCode()
  2. 等于()
  3. 1 和 2

换句话说,

如果hashTable.add(obj1) =>返回true, 和 hashTable.add(obj2) => 返回 false,

检查 obj2 时考虑了哪些因素,导致其从 HashSet 的存储中被拒绝。

我尝试通过重写函数调用来打印日志,但在添加要设置的元素时从未调用 equals()。

  public class HashTest {
     int a,b;
     public HashTest(int a, int b){
     this.a=a;
     this.b=b;
   }
public static void main(String[]args){
    HashSet<HashTest> hashTable=new HashSet<HashTest>();
    HashTest obj1=new HashTest(1, 2);
    HashTest obj2=new HashTest(1, 2);
    System.out.println("1. obj1 hash code:"+obj1.hashCode());
    System.out.println("2. obj2 hash code:"+obj2.hashCode());
    System.out.println("inserting obj1 to the Hash Table:"+hashTable.add(obj1));
    System.out.println("inserting obj2 to the Hash Table:"+hashTable.add(obj2));
}
public boolean equals(Object obj){
    System.out.println("***equals called");
    return super.equals(obj);
}

public int hashCode(){
    System.out.println("***hashCode called");
    return super.hashCode();
}
  }

结果:

***调用的哈希码

  1. obj1 哈希码:4072869

***调用的哈希码

  1. obj2 哈希码:1671711

***调用的哈希码

将 obj1 插入哈希表:true

***调用的哈希码

将 obj2 插入哈希表:true

最佳答案

HashSet 使用 HashMap,如实现所示:

public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

其中mapHashMap的实例。这是HashMap#put(K, V)的实现:

public V put(K key, V value) {
    if (table == EMPTY_TABLE) {
        inflateTable(threshold);
    }
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key);
    int i = indexFor(hash, table.length);
    @SuppressWarnings("unchecked")
    Entry<K,V> e = (Entry<K,V>)table[i];
    for(; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

我认为您现在应该能够回答自己的问题了。

关于java - 哪些因素决定新元素能否通过 HashSet 的添加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18540731/

相关文章:

java - 在 ListDataProvider 中使用通用列表

java - 从父类(super class)继承方法而不是从java 8中实现接口(interface)的默认方法的意义

algorithm - 后缀树 : Longest repeating substring implementation

java - 哈希集的迭代器是如何排序的?

java - 将Android App项目转换为桌面纯java的想法

java - 嵌套的 JScrollPane 不适合

java - 树的分区压缩以及如何将节点压缩到根

c - 只有某些输入的 C 中的段错误

c# - HashSet<T>.Contains() 对于大型列表、多线程是否高效?

scala - Scala 中的 SynchronizedSet 和 set 操作