java - 为什么空的 Java 字符串的哈希码为零?

标签 java hashcode

直到最近,我才发现一个空的 String哈希码为零。这让我感到惊讶,因为 null通常分配的哈希码为零,例如,Objects.hashCode(Object)ArrayList.hashCode() .
这是 JDK 11 source codeString.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 .如果这个想法有缺陷(除了向后兼容性问题),请解释原因。
我发现了其他接近该问题的问题/答案......但没有一个确切的答案:
  • Can a non-empty string have a hashcode of zero?
  • Why doesn't String's hashCode() cache 0?
  • https://stackoverflow.com/a/64082954/257299
  • 最佳答案

    Why does an empty Java String have hash code zero?


    简短的回答是因为它是在 Java 1.2 中指定的方式。 (Java 1.2 规范可能与早期 Java 版本中的实现相匹配。)
    我想不出 String.hashcode("") 的强大技术原因应该为零。
    但是,我不同意您的观点 String.hashCode("")应该是非零的,因为 Objects.hashCode(null)为零。
  • Objects类是在 Java 7 中添加的。同样的 Arrays.hashCode方法是在 Java 1.5 中添加的。所以如果有的话,它是 ObjectsArrays这里是不正确的。
  • hashCode()中没有任何期待定义任何特定的不同值对应该是不同的。充其量更改 "" 的 hashCode 值将是一个小的优化。请注意 String.equals(null)通过 instanceof 有效处理测试。
  • 一个哈希表同时具有 null 是不寻常的。和 ""作为同一个表中的键。事实上,我什至会说这很可能表明存在设计或实现缺陷,您需要为 null 提供条目。和 "" .
  • 可以说 null不应该被支持为 Map关键。我知道null可以用作 HashMap 中的 key 或 LinkedHashMap ,或作为 HashSet 的值.但对于 ConcurrentHashMap 而言,情况并非如此。或 HashTableTreeMapTreeSet .事实上,我从应该知道的消息来源那里听说:
  • 负责集合类型的 Java 设计者认为支持是错误的 null key ,和
  • 这就是原因之一 ConcurrentHashMap不支持这个。


  • 鉴于使用 null应用程序中的键(可以说)被误导了,这是一个突破性的优化,为 null 提供了一个小的改进。键同样被误导。
    可以说实际上并没有多少代码依赖于 String.hashCode 的指定细节。算法。但问题是,无论是我们还是 Java 设计者,都没有一个很好的方法来量化实际上有多少旧应用程序会崩溃1。
    但是打破现有 Java 应用程序的 0.001% 仍然是很多应用程序,并且惹恼了很多 Oracle 客户。这足以使您的想法成为一个非初学者……对于 Java。

    1 - 因为依赖哈希码值是应用程序程序员的错的论点在某种程度上是“反向练习”,这对我来说并不适用。在这种情况下指定算法的事实(无论出于何种原因)意味着程序员应该能够依赖它。

    关于java - 为什么空的 Java 字符串的哈希码为零?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65275756/

    相关文章:

    java - 如何使用dom4j在java中的另一个xml文档中插入一个xml节点作为第一个子节点?

    java - 为什么具有相同数据的两个不同的 HashSet 具有相同的 HashCode?

    java - 为什么 String s1= "cat"和 String s2= new String ("cat"的哈希码相同?

    java - 单元测试等于和哈希码 - 一个复杂的故事

    java - 关于HashMap,重新散列

    java - 在这种情况下有没有更好的方法来调制哈希值?

    java - 在类主体或构造函数中初始化类成员?

    java - 如何计算字符串出现的次数

    java - 使用数组排序

    java - Java 中更快的 GCD(n, m)?