hashSet中的元素顺序

时间:2015-04-16 10:56:20

标签: java hashset

我在java 1.7文档中读过“它不能保证集合的迭代顺序”。 这是什么意思?

我创建了一个HashSet打印其元素1000次。但每次我得到一个固定的订单。 但是顺序与元素的插入顺序不同。

 Set<String> hashSet = new HashSet<>();

    for (int i = 0; i < 10; i++) {
        hashSet.add("Item+" + i);
    }

    for (String s : hashSet) {
        System.out.println(s);
    }

5 个答案:

答案 0 :(得分:2)

您应该尝试在集合中添加更多元素(例如,10.000)。 HashSet的默认容量为16,但是一旦向集合中添加更多元素,它就会在内部重建。在这种情况下,订单可能会改变。

答案 1 :(得分:2)

这意味着您无法确定订单是否相同,例如,如果您在另一个JVM上运行相同的代码。

计算机上的订单始终相同,使用一个特定的JVM 是无关紧要的。如果订单很重要,请考虑使用TreeSetTreeSet将保证订单始终相同,无论您在何处运行代码。

当然:TreeSet要求以某种方式(例如按字母顺序)订购商品。如果您想保留添加元素的顺序,您可能更喜欢List,例如ArrayList

答案 2 :(得分:1)

在哈希集合中,条目按某些内部哈希函数的结果排序。

对于以相同顺序添加到相同集合的条目的相同集,返回顺序将始终相同,但散列函数值也保持不变,除了如果在调用之间重新组织内部结构(即通过扩展或收缩集合) - 在重组时,重新计算内部散列函数的值,并且条目在内部散列表中占据另一个位置。

BTW,哈希集合的入口迭代器只保证你将收到你放在那里的所有未删除的条目。

答案 3 :(得分:1)

对于当前生成和较旧的实现,HashMap或HashSet 中的条目的顺序在理论上是可预测的

但是,预测取决于至少

  • 键的哈希值,
  • 集合或地图的初始容量,
  • 在集合/地图中添加和删除键的精确顺序,
  • 使用的HashSetHashMap的具体实现(行为取决于Java版本,可能依赖于补丁级别),
  • for Java 8及更高版本,无论密钥是否为Comparable

如果您拥有所有这些信息(并且您准备模拟插入/删除序列),则可以准确预测迭代顺序。但是,实施起来会很棘手,而且运行成本很高......


在您的示例中,哈希值相同,初始HashSet容量相同,插入顺序相同,HashSet实现相同。在那些情况下(并且使用了精确的算法),迭代顺序将是可重复的......即使它很难预测。

在这种情况下,订单不是&#34;随机&#34;因为构建HashSet的过程中没有随机性。只是计算复杂而不透明......但确定性。


  

我在java 1.7文档中已经读过&#34;它不能保证集合的#64;的迭代顺序。这是什么意思?

是什么意思是javadoc没有提交任何特定的行为 vis-a-vis 订购。当然,没有承诺便携行为。


另请参阅:Order of values retrieved from a HashMap

答案 4 :(得分:0)

也许你可以看到相同的“排序”,但这不是真的,这取决于JVM所以,如果你想要一个排序列表

  • 如果您有逻辑排序,请使用Collections.sort()或实现您自己的Comparator

  • 如果您希望按插入顺序排序的收藏集使用ListIterator

      

    列表迭代器首先保证您按列表的内部顺序获取列表的元素(也就是插入顺序)。更具体地说,它是按照您插入元素的顺序或您操作列表的顺序。排序可以看作是对数据结构的操纵,有几种方法可以对列表进行排序。