java - 为什么键在 Java 中是不可变的?

标签 java hashtable

为这个相当幼稚的问题道歉,但我相信我自己的回答是幼稚的。我认为键(在 HashTable 中)是不可变的,因为我们不希望以某种方式意外更改键并因此弄乱 HashTable 的排序。这是正确的解释吗?如果是这样,如何才能更正确?

最佳答案

HashTable.put 期间,键被散列并且它的值被存储在基于散列的多个桶(它们是键值对的列表)之一中,例如一些东西喜欢:

bucket[key.hashcode() % numberOfBuckets].add(key, value)

如果键的 hashcode 在插入后发生变化,则它可能位于错误的存储桶中,然后您将无法找到它并且哈希表将错误地返回 null该 key 的任何 get

旁白:了解哈希表的内部工作原理有助于您了解高质量 hashcode 函数对键的重要性。作为一个糟糕的哈希码函数可能会导致桶中键的分布不佳。由于桶只是列表,这会导致大量线性搜索,从而大大降低哈希表的有效性。例如这个可怕的哈希码函数将所有内容都放在一个桶中,因此它实际上只是一个列表。

public int hashcode { return 42; /*terrible hashcode example, don't use!*/ }

这也是素数出现在好的哈希码函数中的原因之一,例如:

public int hashcode {
    int hash = field1.hashcode();
    hash = hash*31 + field2.hashcode(); //note the prime 31
    hash = hash*31 + field3.hashcode();
    return hash;
}

关于java - 为什么键在 Java 中是不可变的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34060994/

相关文章:

java - 将 ArrayList 保存到文件

java - 为什么运行jsp文件时我的所有bean属性都为空

c++ - 如何在不增加 sizeof 的情况下将 bool 添加到结构中(如果结构中有填充)?

perl - 理解我脚本中指向散列的 Perl 指针

java - Unity JNI,C#中从Android Native获取ArrayList<Hashtable<String, String>>

java - linux下如何设置路径?

java - 配置 Tomcat 以使用 SSL

java - 如何使用为服务器定义的相同接口(interface)编写 Restful 客户端

algorithm - 如何在哈希表和Trie(前缀树)之间进行选择?

java - 检查哈希表中的键与其值之间是否存在值