public class Contact
{
int i;
String name;
public Contact(int iVal, String nameVal)
{
i = iVal;
name = nameVal;
}
}
public class MultiMap
{
public static void main (String args[])
{
java.util.HashMap m = new java.util.HashMap();
Contact m1 = new Contact(1, "name");
Contact m2 = new Contact(1, "name");
m.put(m1, "first");
m.put(m2, "second");
System.out.println(m.get(m1));
System.out.println(m.get(m2));
}
}
输出是:
first
second
这种“获取”方法的表现如何?由于m1和M2具有相同的值并且我没有覆盖hashcode(),所以会调用Object类的equals()方法吗?
这是对的吗?
答案 0 :(得分:11)
当你的类没有覆盖hashCode()
和equals(Object o)
方法时,Java只使用对内存中对象的实际引用来计算值(即检查它是否是相同的实例化)班级)。这就是为什么你仍然得到两个结果。
答案 1 :(得分:3)
所有对象都有hashCode()和equals()。如果未覆盖它们,则使用默认实现。默认行为是将所有对象视为不同,除非它们是同一个对象。
为了进行比较,即使你已经覆盖了hashCode和equals,IdentityHashMap也会这样做。
答案 2 :(得分:2)
它将使用对象类的equals和hashcode方法来查找值(因为Contact不会覆盖equals和hashcode方法),所以是的。
答案 3 :(得分:0)
在Contact
课程中,您没有实施hashcode()
和equals()
功能。
当HashMap调用这些方法时,它将在父类中搜索这些方法,在这种情况下是Object。
在这种情况下,将评估堆上的对象位置而不是值。
e.g。对于两个对象o1
和o2
o1.equals(o2) == true
仅在o1 == o2
hashCode()
是Object类的方法。散列码是JVM对象的整数表示。散列码是系统生成的,JVM将对象的地址作为基础(种子)来生成散列码。生成的散列码在不同的执行时间内不必相同。
答案 4 :(得分:0)
是的,这是正确的。任何没有定义自己的equals和hashcode方法的java对象都会继承java.lang.Object上的默认equals和hascode方法。这些默认实现基于对象引用相等,而不是逻辑上相等。由于您使用相同的对象引用调用了get,因此可以从地图返回该对象。
这是一个进一步说明这一点的例子。
java.util.HashMap m = new java.util.HashMap();
Contact m1 = new Contact(1, "name");
Contact m2 = new Contact(1, "name");
m.put(m1, "first");
m.put(m2, "second");
System.out.println(m.get(m1));//first
System.out.println(m.get(m2));//second
System.out.println(m.get(new Contact(1, "name"));//null - since the new object has a different object reference.
答案 5 :(得分:0)
虽然m1和m2具有相同的值,但它们是不同的对象引用。
这是正确的: 没有哈希码方法,因此JVM无法查看对象m1和m2是否包含不同的值 - >所以它使用Object类的hasCode()方法来计算hashCode值来执行get(),它返回不同的哈希值(显而易见)。
第二点也是正确的: 由于您还没有实现自己的equals(),因此只有当一个对象与自身进行比较时,才会考虑Object的equals(),它返回 true 。
答案 6 :(得分:0)
默认情况下,Object类覆盖hashCode和equals方法。这就是您获得所需输出的原因。
如果不重写equals和hashcode方法,JVM会在场景后面检查它。由于m1和m2都是不同的对象实例,因此equals方法始终返回false。 即:
<强> 1。等于:
m1.equals(m2)//返回false,因为两者都是不同的实例。
<强> 2。对于hashCode: //请参阅HashMap.java中的源代码
HashMap内部用于在放入hashMap之前重新发送密钥。见下文。
[![Source code of put method][1]][1]
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
对于rehash,hashMap有自己的静态哈希方法:
[![Source code of hash method][1]][1]
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
在内部,equals和hashCode方法都以这种方式工作,这就是为什么你得到存储在HashMap中的两个值。
希望这会有所帮助:)