何时使用System.identityhashcode()和hashcode()方法?*
答案 0 :(得分:2)
根据javadoc,System.identityHashCode(Object o)
:
返回与默认方法hashCode()返回的给定对象相同的哈希码,无论给定对象的类是否覆盖hashCode()。空引用的哈希码为零。
因此,首先,System.identityHashCode(nullReference)
将始终为您提供0
,而不是nullReference.hashCode()
,这显然会在运行时为您提供NullPointerException
。
但是,请考虑以下课程:
public class MysteriousOne {
@Override
public int hashCode() {
return 0xAAAABBBB;
}
//override equals() and so on...
}
该类覆盖hashCode()
,这是完全正常的,即使每个实例的哈希码都是相同的,但是如果你想要区分几个实例的身份,那么这样就不行了。通常,您可以尝试.toString()
方法的输出(默认情况下会提供类名,后跟@
后跟hashCode()
输出),例如,查找输出对象的真实身份,但在这种情况下,输出将是相同的:
MysteriousOne first = new MysteriousOne();
MysteriousOne second = new MysteriousOne();
System.out.println("First: " + first);
System.out.println("Second: " + second);
输出结果为:
First: MysteriousOne@aaaabbbb
Second: MysteriousOne@aaaabbbb
因此,拥有hashCode()
的这种实现是不可能区分几个实例的身份。这是System.identityHashCode()
方便的地方。
如果你这样做
System.out.println("First: " + System.identityHashCode(first));
System.out.println("Second: " + System.identityHashCode(second));
你为不同的实例得到两个不同的数字,即使它们的类实现的hashCode()
返回一个常量(实际上在这里,hashCode()
的重写实现根本不会被调用,根据javadoc):
First: 366712642
Second: 1829164700
此外,您甚至可以将原语传递给System.identityHashCode(Object o)
,因为它们将被装箱到相应的包装器中:
int i = 5;
System.out.println(System.identityHashCode(i));
更多信息:
答案 1 :(得分:0)
您的某些课程可能会覆盖系统中的hashcode()
方法。对于这些对象,此方法提供从其最终父java.lang.Object
返回的提供的Object的哈希码。请参阅Java API以查看语言设计人员的说明。
我相信当你想要出于某些原因创建几乎非唯一的对象时。当我说差不多时,可能存在具有相同哈希码的对象。实际上,您最少会使用equals
方法。
答案 2 :(得分:0)
public static int identityHashCode(Object x)
返回与默认方法hashCode()返回的给定对象相同的哈希码,无论给定对象的类是否覆盖hashCode()。空引用的哈希码为零。
请注意,identityHashCode
会返回hashCode
类中实现的Object
,而这不是您通常想要的,因此您应该只使用yourObject.hashCode()
。
关于此方法是否可能存在某些用例,如果您有一个Objects
数组,您正在迭代它可能会有一些null
,并且您需要hashCode
使用System.identityHashCode(obj)
这些对象可以为您节省一次空检查,而不是那么大的改进。
答案 3 :(得分:0)
System.identityhashcode()总是返回默认的java.lang.Object实现,即使特定对象的类覆盖了它并计算不同的哈希代码。
在某些情况下,您可能需要这种定义:当且仅当o1 == o2时,两个对象o1和o2被认为是相等的。在正常实现中,当且仅当o1 == null时,两个对象o1和o2被认为是相等的? o2 == null:o1.equals(o2)。 当且仅当o1 == o2时,两个对象相等,它们必须具有相同的哈希码。所以你应该使用System.identityhashcode()。
以下是我遇到的一些代码段。
private static int hash(Object x, int length) {
int h = System.identityHashCode(x);
// Multiply by -127, and left-shift to use least bit as part of hash
return ((h << 1) - (h << 8)) & (length - 1);
}
<强> IdentityHashMap.java 强>
public int hashCode() {
return System.identityHashCode(instance);
}
@Override
@SuppressWarnings("rawtypes")
public boolean equals(final Object other) {
return other instanceof IdentityWrapper &&
((IdentityWrapper) other).instance == instance;
}
IdentityWrapper.java (来自Apache Commons Pool 2)
答案 4 :(得分:-1)
嗯,对于初学者来说,虽然System当然有一个hashCode()
方法(每个Object都有一个),但我没有太多理由在调用它。或者甚至有机会获得一个System对象来调用它,因为System为final
且构造函数为private
。所以,对于hashCode()
,可能“几乎从不”,我猜。
所以,这给我们留下了System.identityHashCode(Object)
,它为您提供了任何Object的默认哈希码值。所以,换句话说,你不经常需要它,因为如果你没有覆盖你的类中的hashCode()方法,你的对象默认会得到相同的返回值(因为实际上是默认的hashCode) (),当你没有覆盖hashCode()方法时,只是System.identityHashCode(this)
)。可能有一些使用案例何时使用,但它们非常罕见。