Java如果hashCode相同且equals为真,HashMap如何识别key对象?
Java how does HashMap identify the key object if hashCode are the same and equals is true?
我一直以为HashMap是通过hasCode和equals来识别key的。但是这段代码仍然没有给我返回值。我错过了什么?
import java.util.HashMap;
import java.util.Map;
/**
* Created by kic on 25.04.15.
*/
public class TypePair {
private final Class a;
private final Class b;
public TypePair(Class a, Class b) {
this.a = a;
this.b = b;
}
public TypePair(Object a, Object b) {
this.a = a.getClass();
this.b = b.getClass();
}
public boolean isPair (Object a, Object b) {
return this.a.isAssignableFrom(a.getClass()) && this.b.isAssignableFrom(b.getClass());
}
@Override
public boolean equals(Object obj) {
if (obj instanceof TypePair) {
return a.isAssignableFrom(((TypePair) obj).a) && b.isAssignableFrom(((TypePair) obj).b);
} else {
return false;
}
}
@Override
public int hashCode() {
return 1;
}
public static void main(String[] args) {
TypePair a = new TypePair(Number.class, String.class);
TypePair b = new TypePair(12, "hello");
Map<TypePair, Boolean> test = new HashMap<>();
test.put(a, true);
System.out.println(a.hashCode() == b.hashCode());
System.out.println(a.equals(b));
System.out.println("und? " + test.get(a));
System.out.println("und? " + test.get(b));
}
}
此代码打印:
true
true
und? true
und? null
您对 equals()
的实现违反了契约(它不是对称的),这就是它无法正常工作的原因。
您需要使用类似的东西:
@Override
public boolean equals(Object obj) {
if (obj instanceof TypePair) {
TypePair objTypePair = (TypePair) obj;
return a .isAssignableFrom(objTypePair.a) && b .isAssignableFrom(objTypePair.b) ||
objTypePair.a.isAssignableFrom(a) && objTypePair.b.isAssignableFrom(b);
} else {
return false;
}
}
我一直以为HashMap是通过hasCode和equals来识别key的。但是这段代码仍然没有给我返回值。我错过了什么?
import java.util.HashMap;
import java.util.Map;
/**
* Created by kic on 25.04.15.
*/
public class TypePair {
private final Class a;
private final Class b;
public TypePair(Class a, Class b) {
this.a = a;
this.b = b;
}
public TypePair(Object a, Object b) {
this.a = a.getClass();
this.b = b.getClass();
}
public boolean isPair (Object a, Object b) {
return this.a.isAssignableFrom(a.getClass()) && this.b.isAssignableFrom(b.getClass());
}
@Override
public boolean equals(Object obj) {
if (obj instanceof TypePair) {
return a.isAssignableFrom(((TypePair) obj).a) && b.isAssignableFrom(((TypePair) obj).b);
} else {
return false;
}
}
@Override
public int hashCode() {
return 1;
}
public static void main(String[] args) {
TypePair a = new TypePair(Number.class, String.class);
TypePair b = new TypePair(12, "hello");
Map<TypePair, Boolean> test = new HashMap<>();
test.put(a, true);
System.out.println(a.hashCode() == b.hashCode());
System.out.println(a.equals(b));
System.out.println("und? " + test.get(a));
System.out.println("und? " + test.get(b));
}
}
此代码打印:
true
true
und? true
und? null
您对 equals()
的实现违反了契约(它不是对称的),这就是它无法正常工作的原因。
您需要使用类似的东西:
@Override
public boolean equals(Object obj) {
if (obj instanceof TypePair) {
TypePair objTypePair = (TypePair) obj;
return a .isAssignableFrom(objTypePair.a) && b .isAssignableFrom(objTypePair.b) ||
objTypePair.a.isAssignableFrom(a) && objTypePair.b.isAssignableFrom(b);
} else {
return false;
}
}