java 对象作为没有哈希码和等于的 Map 键
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6871929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Objects as Map keys without Hashcode and equals
提问by Ved
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));
}
}
Output is:
输出是:
first
second
How does this "get" method behave ? As both m1 and M2 have same values and I have not overridden hashcode(), will Object class's equals() method be called ?
这个“get”方法的行为如何?由于 m1 和 M2 具有相同的值并且我没有覆盖 hashcode(),所以会调用 Object 类的 equals() 方法吗?
Is this correct ?
这个对吗 ?
- There is no hashcode method so there is no way for the JVM to see if objects m1 and m2 contain different values
- There is no equals method overridden so Object class's equals() is invoked and as both objects are different the code above works fine without m2 replacing m1's value.
- 没有哈希码方法,因此 JVM 无法查看对象 m1 和 m2 是否包含不同的值
- 没有覆盖 equals 方法,因此调用对象类的 equals() 并且由于两个对象不同,上面的代码可以正常工作,而无需 m2 替换 m1 的值。
采纳答案by Nico Huysamen
When the hashCode()
and equals(Object o)
methods are not overridden by your class, Java just uses the actual reference to the object in memory to calculate the values (ie. check if it is the same instantiation of the class). That is why you still get both results.
当您的类没有覆盖hashCode()
和equals(Object o)
方法时,Java 仅使用对内存中对象的实际引用来计算值(即检查它是否与类的实例化相同)。这就是为什么你仍然得到两个结果。
回答by Peter Lawrey
All Objects have hashCode() and equals(). When they are not overridden, the default implementations are used. The default behaviour is to treat all objects as different, unless they are the same object.
所有对象都有 hashCode() 和 equals()。当它们未被覆盖时,将使用默认实现。默认行为是将所有对象视为不同对象,除非它们是同一个对象。
For comparison, the IdentityHashMap always does this even if you have overridden you hashCode and equals.
为了进行比较,即使您覆盖了 hashCode 和 equals,IdentityHashMap 也总是这样做。
回答by Low Flying Pelican
It will use equals and hashcode method of object class to find the value (as Contact does not overide equals and hashcode methods), so yes.
它将使用对象类的 equals 和 hashcode 方法来查找值(因为 Contact 不会覆盖 equals 和 hashcode 方法),所以是的。
- Yes, Java will always see two Contact objects are different as it will use object reference to compare when it using the equals method in object
- Yes, as two contact objects have to references.
- 是的,Java 总是会看到两个不同的 Contact 对象,因为它在对象中使用 equals 方法时会使用对象引用进行比较
- 是的,因为两个联系人对象必须引用。
回答by Sanchit
By default Object class override the hashCode and equals method. This is the reason you get the desired output.
默认情况下,Object 类会覆盖 hashCode 和 equals 方法。这就是您获得所需输出的原因。
If you do not override equals and hashcode method, JVM checks it behind the scene. As m1 and m2 both are different object instances, equals method always return false. i.e :
如果您不覆盖 equals 和 hashcode 方法,JVM 会在幕后检查它。由于 m1 和 m2 都是不同的对象实例,equals 方法总是返回 false。IE :
1. For equals:
1. 对等:
m1.equals(m2) //return false because both are different instances.
m1.equals(m2) //return false 因为两者是不同的实例。
2. For hashCode://See the source code inside HashMap.java
2.对于hashCode://查看HashMap.java里面的源码
HashMap internally uses to rehash the key before putting in hashMap. See bellow.
HashMap 内部用于在放入 hashMap 之前重新哈希键。见下文。
[![Source code of put method][1]][1]
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
for the rehash, hashMap has it's own static hash method:
对于重新哈希,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);
}
Internally, both equals and hashCode method work in this way, that is why you get both the values stored in the HashMap.
在内部,equals 和 hashCode 方法都以这种方式工作,这就是为什么您将两个值都存储在 HashMap 中的原因。
Hope this helps :)
希望这可以帮助 :)
回答by Swagatika
Though m1 and m2 have the same values they are different object references.
尽管 m1 和 m2 具有相同的值,但它们是不同的对象引用。
This is correct : There is no hashcode method so there is no way for the JVM to see if objects m1 and m2 contain different values -> So it uses the Object class's hasCode() method to calculate the hashCode value to execute the get(), which return different hash values(obvious).
这是正确的:没有 hashcode 方法,因此 JVM 无法查看对象 m1 和 m2 是否包含不同的值 -> 因此它使用 Object 类的 hasCode() 方法计算 hashCode 值以执行 get() , 返回不同的哈希值(显而易见)。
the second point is also correct: As you have not implemented your own equals(), will consider Object's equals() which returns trueonly when one object is compared to itself.
第二点也是正确的:由于您还没有实现自己的equals(),将考虑对象的equals(),它仅在一个对象与其自身进行比较时才返回true。
回答by Talha Ahmed Khan
Here in Contact
class you did not implement the hashcode()
and equals()
functions.
在Contact
课堂上,您没有实现hashcode()
和equals()
函数。
When HashMap call these method it will search out for these method in the parent class which is Object in this case.
当 HashMap 调用这些方法时,它将在父类中搜索这些方法,在这种情况下是 Object。
In this case the object location on the Heap is evaluated instead of the values.
在这种情况下,将评估堆上的对象位置而不是值。
e.g. For two objects o1
and o2
例如对于两个对象o1
和o2
o1.equals(o2) == true
only when o1 == o2
o1.equals(o2) == true
只有当 o1 == o2
hashCode()
is a method of Object class. Hash code is an integer representation of an object by JVM. Hash code is system generated and JVM takes the address of the object as the basis (seed) to generate the hash code. Hash codes generated need not be the same for different times of execution.
hashCode()
是Object类的一个方法。哈希码是 JVM 对象的整数表示。哈希码是系统生成的,JVM 以对象的地址为基础(种子)生成哈希码。对于不同的执行时间,生成的哈希码不必相同。
回答by mR_fr0g
Yes this is correct. Any java object that does not define its own equals and hashcode methods inherit the default equals and hascode methods on java.lang.Object. These default implementation are based on object reference equality and not on logically equality. Since you have called get with the same object reference the object can be returned from the map.
是的,这是正确的。任何没有定义自己的equals 和hashcode 方法的java 对象都会继承java.lang.Object 上的默认equals 和hascode 方法。这些默认实现基于对象引用相等而不是逻辑相等。由于您使用相同的对象引用调用了 get,因此可以从映射中返回对象。
Here is an example that illistrates this further.
这是一个进一步说明这一点的例子。
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.