我想知道在向 HashSet
添加新元素(对象)之前检查哪些因素(1、2 或 3?)?
如果 HashSet
中存在唯一元素(对象),并且我们尝试添加新对象,则该集合是否仅比较哈希码或使用 equals()
的引用或两者?
HashCode()
等于()
- 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();
}
}
结果:
***调用的哈希码
- obj1 哈希码:4072869
***调用的哈希码
- obj2 哈希码:1671711
***调用的哈希码
将 obj1 插入哈希表:true
***调用的哈希码
将 obj2 插入哈希表:true
最佳答案
HashSet
使用 HashMap
,如实现所示:
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
其中map
是HashMap
的实例。这是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/