这是一个两部分的问题:
- HashSet 是否实现了一些隐藏的排序机制,或者只是它,引用文档:
它不保证集合的迭代顺序;特别是,它不保证顺序会随着时间的推移保持不变。
告诉我顺序可能会在将来和/或根据内存使用情况改变? - 为什么我在 JDK 之间切换时得到完全不同的“排序”(我敢说)?
举个例子:
for (int i = 0; i < 1000; i++) {
Set<String> 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]>
/21 p>
JDK 8:[, qwes, arfskt6743, asdxasdq, 123121, 123121 , arfskt6734, qwr, 123, 1234, qwea, rtzz, rtz, 12334rasefasd, 1234rasefasd, qwe, asdxasd]>
xasd] p>
显然,空字符串和纯空白字符串两次都处于领先地位,但其余部分完全不同。
最佳答案
根据馆藏更新changes page
The alternative String hash function added in 7u6 has been removed from JDK 8, along with the jdk.map.althashing.threshold system property. Instead, hash bins containing a large number of colliding keys improve performance by storing their entries in a balanced tree instead of a linked list. This JDK 8 change applies only to HashMap, LinkedHashMap, and ConcurrentHashMap.
In rare situations, this change could introduce a change to the iteration order of HashMap and HashSet. A particular iteration order is not specified for HashMap objects - any code that depends on iteration order should be fixed.
所以,基本上
散列集合的算法已更改以提高性能。它改为平衡树而不是链表。
这种变化可能改变你的集合的迭代顺序,并且确定这种行为应该由你修复,如果你依赖它的话。
您看到了一个更好的集合实现,它可能看起来是有序的,但这纯属巧合。
我建议您不要依赖集合的迭代顺序,因为顺序并不能保证。
@编辑
另一个概念也很重要,正如用户 Holger 所说,
The “alternative String hash function” of Java 7 was not used by default. Further, the balanced tree only applies to bucket collision scenarios. Still, as a consequence of this improvement, another, unmentioned change has been made. The mapping of an object’s hashcode to an array position undergoes a transformation which has been simplified from Java 7 to Java 8
关于java - HashSet顺序及与JDK 7/8的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45573023/