这是我的测试课..
import java.util.HashMap;
public class Test {
public static void main(String[] args) {
A a = new A(0, 1);
HashMap<A, Integer> map = new HashMap<A, Integer>();
map.put(a, (a.x + a.y));
System.out.println(map.containsKey(a));
System.out.println("----------------- ");
System.out.println(map.containsKey(new A(0, 1)));
}
}
这是我的A类,其中包含hashcode和eclipse生成的相等方法。
class A {
int x, y;
public A(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
System.out.println(" in hashcode");
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
System.out.println(" in equal");
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
程序的输出是
in hashcode
in hashcode
true
-----------------
in hashcode
in equal
true
我的问题是:(我知道哈希码的合同和等号以及为什么使用它)
答案 0 :(得分:9)
1)调用put时调用getHashCode,调用contains时调用getHashCode。
2)在第一种情况下,hashmap包含对a的引用,即内存中的地址,因此不需要调用equals。在第二种情况下,表查找找到a,但这是与您作为参数提供的新A不同的对象,因此需要调用equals()以查明它们是否相等(它们可能不同)并且具有相同的哈希码,这将是一次冲突。)
答案 1 :(得分:4)
如果你看一下HashMap.containsKey的源代码,你会发现以下内容(取自这里:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/HashMap.java#HashMap.containsKey%28java.lang.Object%29)
public boolean containsKey(Object key) {
return getEntry(key) != null;
}
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
重要的部分是(k = e.key) == key || (key != null && key.equals(k))
。 metod首先通过引用比较关键对象,然后使用equals方法进行比较,但前提是引用不同。
在您第一次调用containsKey
时,关键引用将是相同的(同一个对象)。在第二个调用中,引用将是不同的(&#34;等于&#34;对象的不同实例),因此调用equals
。
答案 2 :(得分:2)
您可以在@ kresimir-nesek粘贴代码中查看
首先获取hashCode:int hash = (key == null) ? 0 : hash(key.hashCode());
并在哈希码中打印“
然后比较java对象标识符(k = e.key) == key
1)在第一种情况下是相同的并返回true。调用map.put,您将获得哈希码中的第二个“
2)但在第二种情况下,对象标识符是不同的,所以调用equals(... (key != null && key.equals(k))
...)
“相等”