直到最近,我才发现 String
哈希代码为零。我很惊讶因为 null
通常分配哈希码为零,例如。, Objects.hashCode(Object)
以及 ArrayList.hashCode()
.
以下是JDK11的源代码 String.hashCode()
:
/**Cache the hash code for the string */
private int hash; // Default to 0
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
hash = h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
}
return h;
}
想法:一个空的 String
可能有散列码1,因为那会匹配 Arrays.hashCode(Object[])
对于空数组。或者,可以使用任何其他硬编码的非零值,类似于 serialVersionUID
. 目的是区别于 null
. 如果这个想法有缺陷(除了向后兼容性问题),请解释原因。
我发现其他问题/答案接近这个问题。。。但没有人确切回答:
非空字符串的哈希码是否为零?
为什么string的hashcode()不能缓存0?
https://stackoverflow.com/a/64082954/257299
2条答案
按热度按时间camsedfj1#
为什么空java字符串的哈希代码为零?
简单的回答是因为它是在Java1.2中被指定的(Java1.2规范可能与早期java版本中的实现相匹配。)
我想不出一个强有力的技术原因
String.hashcode("")
应该是零。但是,我不同意你的论点
String.hashCode("")
应为非零,因为Objects.hashCode(null)
是零。这个
Objects
类是在Java7中添加的。同样地Arrays.hashCode
方法是在Java1.5中添加的。所以如果有什么的话,那就是Objects
以及Arrays
这是不正确的。世界上没有期望
hashCode()
任何特定的不同值对应该是不同的定义。最多更改""
会是一个小的优化。请注意String.equals(null)
通过instanceof
测试。哈希表两者兼有是不寻常的
null
以及""
作为同一表中的键。事实上,我甚至可以说,它很可能表示一个设计或实现缺陷,您需要为这两个缺陷都添加条目null
以及""
.可以说
null
不应作为Map
一点都不重要。我知道null
可以用作HashMap
或者LinkedHashMap
,或作为HashSet
. 但事实并非如此ConcurrentHashMap
或者HashTable
或者TreeMap
或者TreeSet
. 事实上,我从应该知道的人那里听说:负责集合类型的java设计者认为支持这些类型是一个错误
null
钥匙,和这就是为什么
ConcurrentHashMap
不支持这个。鉴于
null
应用程序中的键(可以说)被误导了,这是一种突破性的优化,可以为null
钥匙也同样被误导了。可以说,实际上没有多少代码依赖于
String.hashCode
算法。但问题是,无论是我们还是java设计者都没有一个好的方法来量化有多少旧的应用程序会真正崩溃。但是,现有java应用程序中只有0.001%的应用程序被破坏,这仍然是一个很大的应用程序问题,也是很多令oracle客户恼火的问题。这足以让你的想法成为一个不起眼的想法。。。对于java。
1-那种认为依赖hashcode值是应用程序程序员的错的观点不知何故是“反向实践”,我不理解。在这种情况下(无论出于什么原因)指定了算法这一事实意味着程序员应该能够依赖它。
rmbxnbpk2#
这个
hashCode()
最初的目的是This method is supported for the benefit of hash tables such as those provided by HashMap.
因此这意味着hashcode的实际值除了可能的相似性之外没有任何意义,正如doc所说:It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results.
关于任意值0
对于空字符串和空字符串,字符串哈希代码的计算方式会导致其他可能的错误0
hashcode甚至用于非空字符串。所以
0
空字符串的值是有意义的,因为计算是所以即使是捷径
if (h == 0 && value.length > 0)
如果没有使用,仍然会导致0
,这只是一条优化路径。在某种程度上,人们可以说
null
哈希代码不应为空0
但也许是这样的-1
. 但是,既然hashcode没有也不应该带有任何意义,那么它无论如何也不重要。