java - HashSet顺序及与JDK 7/8的区别

标签 java collections hashset

这是一个两部分的问题:

  1. HashSet 是否实现了一些隐藏的排序机制,或者只是它,引用文档:它不保证集合的迭代顺序;特别是,它不保证顺序会随着时间的推移保持不变。 告诉我顺序可能会在将来和/或根据内存使用情况改变?
  2. 为什么我在 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/

相关文章:

Linq 子集合标准,其中集合是 double 列表

scala - 概括收集方法

java - PayPal Webhook 验证 Java SDK

java - 如何比较两个包含具有共享属性的对象的数组列表

Java批量重启不处理步骤

java - hashSet 如何接纳元素

java - 对于非常大的数据集,我应该使用 `HashSet` 还是 `TreeSet`?

java - 在没有自定义类的情况下覆盖 equals

java - JQuery.ajax 错误。无法弄清楚问题所在

java - Atmosphere 样本 : Can't get chat demo working (atmosphere. js 给出 404)