根据这篇文章的评论,hascode
null objects
可以throw NPE
或值为zero
。这是特定于实现的。但是在同一实现中,为什么Objects.hashcode
和hascode(instance)
返回不同的值。例如:
public class EqualsTesting {
public static void main(String[] args){
String p1 =null;
String p2 = null;
System.out.println(Objects.hashCode(p1));
System.out.println(p2.hashCode());
}
}
输出:
0
Exception in thread "main" java.lang.NullPointerException
at BinaryTrees.EqualsTesting.main(EqualsTesting.java:14)
如果是这种情况,这是否不会影响允许null Key-value pairs
的HashMap
key look-up
。(它可能hash
bucket 0
或throw a NPE
)
如何计算甚至不存在的对象hashCode
?当p2
被null
时,调用它上面的任何方法都会抛出NPE
。这并没有给你任何特定的哈希代码值。
Objects.hashCode()
只是一个包装方法,它对null
值执行预检查,对于未null
的引用,它返回与p2.hashCode()
相同的值,就像在这种情况下一样。下面是该方法的源代码:
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}
如果你四处搜索,你会发现HashMap
对null
键有特殊的处理。null
值很好,因为您不会在HashMap
中为它们计算哈希代码。这就是为什么null
键在HashMap
中工作正常的原因。至于为什么Objects.hashCode
工作正常,看看罗希特的回答。
正如javadoc所说:
Objects.hashCode(Object o)
返回非空参数的哈希代码和 null 的 0 论点。
p2.hashCode()
引发NullPointerException
,因为您正在尝试访问 null 对象的方法。
根据这篇文章的评论,空对象的 hascode 可以抛出 NPE 或零值。
事实并非如此。 (这不是@Bohemian的评论所说的!
在HashMap
和HashSet
中发生的事情是,他们将null
视为特例。 他们没有在null
对象上调用hashcode()
(这将NPE!!),而是使用零作为硬编码的替代哈希码。
我强调...这是HashMap
和HashSet
的特殊情况行为...不hashcode()
.
如您的示例所示,如果您尝试在null
上调用hashcode()
方法,您将获得一个 NPE。JLS说这就是将要发生的事情...每当您尝试在null
上调用任何实例方法时,都会发生这种情况。
(另一方面,Objects.hashCode(obj)
方法确实处理obj
null
特例的情况。 这就是静态方法的重点!
null
的哈希码为 0(见Objects.hash()
)
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
0 是 Hashmap 中null的硬编码值。您可以看到在 HashMap 和 Objects java 类中完成的以下实际实现。
来自哈希地图.java
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
从对象.java
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}