【问题标题】:Java default string hash function produces collisions on single character stringsJava 默认字符串散列函数在单个字符串上产生冲突
【发布时间】:2015-09-07 10:01:33
【问题描述】:

我是一名 CS 学生,如果我说的话听起来太荒谬,请多多包涵。这对我来说肯定是这样,这就是为什么我在这里寻找答案。 我阅读了如何在 Java 中对字符串进行哈希处理,然后查看了 ASCII 表。字母“d”和“n”分别哈希为 100 和 110。现在,如果我要在 Java 中创建一个全新的 hashmap,默认情况下它有 10 个桶。因此,即使哈希码是唯一的,但 mod 10 它们都是 0。这会导致冲突。 在 1 个字符串上发生冲突对我来说并不合适,那么我描述的过程是否正确? 提前致谢。

【问题讨论】:

    标签: java hash hashmap hashtable


    【解决方案1】:

    哈希实际上在基于哈希的集合中用作索引或分组机制。哈希不用作实际参考。哈希用于查找元素可能首先包含的桶。

    正如您所说,dn 可以包含在同一个存储桶中,但之后在这种情况下,dn 的实际值可用于引用实际对象。由于 Hashmap 不允许重复键,因此您可以确定始终存在一个 d 和一个 n

    【讨论】:

    • 但理想情况下(如果没有冲突),每个桶都包含一对(键,值)对吗?因此,dn 最终都在同一个存储桶中这一事实在定义上是冲突。这不正确吗?
    • 虽然现在想来,如果我在地图中插入更多元素,超过负载因子,就会添加更多的桶,越来越少的单个字符会在一个桶中结束,最终导致每个角色都有自己的桶。
    • @user96454:很好的洞察力。随着表格的增长,一些早期冲突的元素被分离,但请注意,一些统计上较少数量的键可能会在增长后通过重新散列而新发生冲突,并且您不能在统计上期望(即> 50% 的机会)不会发生冲突,除非存储桶的数量大大大于键的数量 - 很大程度上是由于 birthday problem - 这将非常浪费内存,它比很少发生碰撞。在一般情况下,您肯定会遇到一些冲突。
    【解决方案2】:

    您所描述的可能是正确的,由于pigeonhole principle,两者都会落在同一个桶上,这基本上意味着如果您的物品多于放置它们的孔,则两个或更多最终会落在同一个孔上.在这种情况下,仅考虑 95 个可打印的 ASCII 字符,原则规定每个孔中至少有 10 个(不考虑实际值,仅考虑它们的数量)。

    但是,shazin 的回答也是正确的,因为哈希值实际上并未用作映射中值的标识,而是用于查找 kay/value 对所属的存储桶,然后在使用equals() 方法(或==,如果使用IdentityHashMap)检查存储桶是否相等。

    【讨论】:

    • +1 表示皮江洞原理。当只有 10 个存储桶时,如果想出一个可以将每个单个字符放在一个唯一存储桶中的哈希函数,那将是令人印象深刻的......
    • Java 的 0.75 加载因子会随着我们添加更多元素而增加存储桶的数量,这并不是说我们添加了所有 95 个元素而存储桶的数量保持不变 10。
    • 确实如此,但重点仍然是,给定一个大于初始桶数的域,第一个元素肯定会发生冲突
    猜你喜欢
    • 2011-04-11
    • 2013-11-16
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 2011-09-30
    • 2012-03-21
    • 2011-02-07
    • 2013-07-10
    相关资源
    最近更新 更多