Java 是JDK 8’;s处理HashMap冲突的新策略(树而不是列表)只需要那些不能编写好的hashcode()的人就可以了?
在Java8中,当 一个bucket中的元素数达到某个阈值 问:提到的改进只是关心那些不知道如何编写适当的hashcode()方法的程序员吗?或者它在其他情况下有用吗?在什么情况下不可能编写好的hashcode()方法?换句话说,在某些情况下,即使是非常好的hashcode()方法也不能防止冲突,并且树是可行的吗? 在提供最坏情况下的O(log n)操作时,当键具有不同的散列或可排序时,树容器的额外复杂性是值得的,因此,在偶然或恶意使用情况下,性能会下降,其中hashCode()方法返回的值分布不均,以及许多键共享一个散列代码,只要它们是可比的 这一改进可防止拒绝服务攻击,即对手故意挑选将落入同一桶的值。不可能编写具有弹性的哈希代码,因为它在JVM实例之间也是稳定的。 在提供最坏情况下的O(log n)操作时,当键具有不同的散列或可排序时,树容器的额外复杂性是值得的,因此,在偶然或恶意使用情况下,性能会下降,其中hashCode()方法返回的值分布不均,以及许多键共享一个散列代码,只要它们是可比的Java 是JDK 8’;s处理HashMap冲突的新策略(树而不是列表)只需要那些不能编写好的hashcode()的人就可以了?,java,hashmap,hashset,Java,Hashmap,Hashset,在Java8中,当 一个bucket中的元素数达到某个阈值 问:提到的改进只是关心那些不知道如何编写适当的hashcode()方法的程序员吗?或者它在其他情况下有用吗?在什么情况下不可能编写好的hashcode()方法?换句话说,在某些情况下,即使是非常好的hashcode()方法也不能防止冲突,并且树是可行的吗? 在提供最坏情况下的O(log n)操作时,当键具有不同的散列或可排序时,树容器的额外复杂性是值得的,因此,在偶然或恶意使用情况下,性能会下降,其中hashCode()方法返回的值分布
这一改进可防止拒绝服务攻击,即对手故意挑选将落入同一桶的值。不可能编写适应这种情况的哈希代码,因为JVM实例之间的哈希代码也是稳定的。如果向哈希映射添加足够的条目,从统计上讲,就会出现bucket冲突。注意,bucket冲突与hashCode冲突不是一回事;虽然哈希代码冲突总是导致bucket冲突,但任何2个哈希代码都有1/bucket计数的机会命中同一个bucket 如果由于运气不好(许多不同的密钥恰好落在同一个bucket中)或编码错误(选择不当的算法会为不同的密钥生成相同的hashCode),bucket中的密钥数量会增加,则检索的时间复杂度为O(n),但现在为O(logn)
考虑到hashCode算法不一定“编码错误”。这可能是因为您正在使用第三方库中的对象作为密钥,因此此更改也可以保护您免受其他人的恶意代码的攻击。如果您向HashMap添加了足够多的条目,从统计上讲,您将遇到bucket冲突。注意,bucket冲突与hashCode冲突不是一回事;虽然哈希代码冲突总是导致bucket冲突,但任何2个哈希代码都有1/bucket计数的机会命中同一个bucket 如果由于运气不好(许多不同的密钥恰好落在同一个bucket中)或编码错误(选择不当的算法会为不同的密钥生成相同的hashCode),bucket中的密钥数量会增加,则检索的时间复杂度为O(n),但现在为O(logn) 考虑到hashCode算法不一定“编码错误”。这可能是因为您正在使用第三方库中的对象作为密钥,所以此更改也可以保护您免受其他人的恶意代码攻击 在什么情况下不可能编写好的hashcode()方法 嗯,除了有人试图通过工程散列冲突来欺骗你的用例之外 在这种情况下,基于全值的hashcode计算过于昂贵,因此您实现了一个“廉价且令人愉快”的版本。但是这个版本有一些边缘情况,你会遇到碰撞 例如,您使用大数组的包装器或哈希映射树作为键。(显然,这种方法存在问题,但有些人无论如何都会这么做。) 在什么情况下不可能编写好的hashcode()方法 嗯,除了有人试图通过工程散列冲突来欺骗你的用例之外 在这种情况下,基于全值的hashcode计算过于昂贵,因此您实现了一个“廉价且令人愉快”的版本。但是这个版本有一些边缘情况,你会遇到碰撞
例如,您使用大数组的包装器或哈希映射树作为键。(显然这种方法存在问题,但有些人无论如何都会这么做。)您的哈希代码可能不会按照您认为的方式在
哈希映射中进行解释。
例如,当您创建一个HashMap
时,如下所示:
Map<String, String> map = new HashMap<>();
hashCode是一个int
,它是有限的,因此哈希冲突非常常见。IIRC forInteger.MAX_VALUE
hash冲突大约会从几万开始(44_000?或类似的,我不记得了)
您的哈希代码可能不会按照您认为的方式在
哈希映射中进行解释。
例如,当您创建一个HashMap
时,如下所示:
Map<String, String> map = new HashMap<>();
hashCode是一个int
,它是有限的,因此哈希冲突非常常见。IIRC forInteger.MAX_VALUE
hash冲突大约会从几万开始(44_000?或类似的,我不记得了)