作者:zengqingwei1220 | 来源:互联网 | 2023-01-26 09:41
这是一个两部分问题:
HashSet是否实现了一些隐藏的排序机制,或者只是引用文档:It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.
告诉我,将来MIGHT有时会改变和/或取决于内存使用情况?
当我在JDK之间切换时,为什么我会得到完全不同的"排序"(我敢说)?
举个例子:
for (int i = 0; i <1000; i++) {
Set stringSet = new HashSet<>();
stringSet.add("qwe");
stringSet.add("rtz");
stringSet.add("123");
stringSet.add("qwea");
stringSet.add("12334rasefasd");
stringSet.add("asdxasd");
stringSet.add("arfskt6734");
stringSet.add("123121");
stringSet.add("");
stringSet.add("qwr");
stringSet.add("rtzz");
stringSet.add("1234");
stringSet.add("qwes");
stringSet.add("1234rasefasd");
stringSet.add("asdxasdq");
stringSet.add("arfskt6743");
stringSet.add("123121 ");
stringSet.add(" ");
System.out.println(stringSet);
}
无论我运行多少次,都会产生以下输出:
JDK 7: [, , 123, qwea, asdxasdq, qwe, qwr, 123121 , arfskt6743, 1234rasefasd, qwes, rtz, rtzz, 1234, 12334rasefasd, asdxasd, arfskt6734, 123121]
JDK 8: [, , qwes, arfskt6743, asdxasdq, 123121, 123121 , arfskt6734, qwr, 123, 1234, qwea, rtzz, rtz, 12334rasefasd, 1234rasefasd, qwe, asdxasd]
显然,空字符串和仅空白字符串两次都是引导方式,但其余部分完全不同.
1> Kerooker..:
根据集合更改页面上的更新
7u6中添加的备用String散列函数已从JDK 8中删除,同时还有jdk.map.althashing.threshold系统属性.相反,包含大量冲突键的哈希箱通过将其条目存储在平衡树而不是链表中来提高性能.此JDK 8更改仅适用于HashMap,LinkedHashMap和ConcurrentHashMap.
在极少数情况下,此更改可能会引入对HashMap和HashSet的迭代顺序的更改.没有为HashMap对象指定特定的迭代顺序 - 任何依赖于迭代顺序的代码都应该被修复.
所以,基本上
用于散列集合的算法已更改以提高性能.它变为平衡树而不是链表.
这种更改可能会改变您的集合的迭代顺序,并且已确定您应该修复此类行为,如果您依赖它.
你看到了一个更好的集合实现,它可能看起来像是有序的,但它纯属巧合.
我建议你不要依赖集的迭代顺序,因为顺序不是保证.
@编辑
如用户Holger所述,另一个概念也很重要,
默认情况下不使用Java 7的"替代字符串散列函数".此外,平衡树仅适用于桶冲突场景.尽管如此,由于这种改进,还有另一个未提及的变化.对象的哈希码到数组位置的映射经历了从Java 7简化到Java 8的转换
请注意,默认情况下不使用Java 7的"替代字符串散列函数".此外,平衡树仅适用于*桶碰撞*场景.尽管如此,由于这种改进,还有另一个未提及的变化.对象的哈希码到数组位置的映射经历了从[Java 7]简化的转换(http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43 /java/util/HashMap.java#360)到[Java 8](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/HashMap的.java#336)...