以下代码生成输出[1,2]
,即使hashset未排序。
Set set = new HashSet();
set.add(new Integer(2));
set.add(new Integer(1));
System.out.println(set);
为什么?
答案 0 :(得分:10)
编辑:从Java 8及更高版本开始,以下内容不再适用。这证明您不应该依赖未记录的Java行为。
此行为是由几个不同原因引起的:
HashMap
和HashSet
由数组备份因此,如果您向hashmap / hashset添加几个小(< 16)整数,则会发生以下情况:
i
具有哈希码i
i
i
请注意,如果存储桶的初始数量太小,整数可能会落在之后没有编号的存储桶中:
HashSet<Integer> set = new HashSet<>(4);
set.add(5); set.add(3); set.add(1);
for(int i : set) {
System.out.print(i);
}
打印153
。
答案 1 :(得分:5)
根据文档的HashSet
并不保证任何订单概念,因此您所看到的内容在未来的Java更新中可能会发生很大变化。
但是,如果您想知道为什么Java(截至目前)HashSet
的具体实现会产生您所看到的结果:这是因为值Integer
的{{1}}哈希值1
的内部条目表中位于之前 HashMap
哈希值的位置的位置(注意2
确实由{HashSet
支持1}}具有任意值)。这是有道理的,因为HashMap
对象的哈希码只是它的值。
事实上,即使添加更多数字(在一定范围内:条目表的大小默认为16),您也可以看到这一点:
Integer
[0, 1, 2, 3, 4]
通过迭代内部条目表来进行Set<Integer> set = new HashSet<>();
set.add(2);
set.add(1);
set.add(4);
set.add(3);
set.add(0);
System.out.println(set);
的迭代,这意味着表格中较早的项目首先出现。
答案 2 :(得分:1)
HashSet是一个无序集合。它没有保证,也没有“订购”的概念。有关详细信息,请参阅此答案:What is the difference between Set and List?
如果您需要有序,有序的Set。
,可以考虑使用TreeSet对于未排序的有序集合,还有LinkedHashSet。
答案 3 :(得分:0)
java中的set
不应该是有序列表。请改用ArrayList
。另请参阅Java Collection API以获取进一步的参考。
答案 4 :(得分:0)
经过多次尝试和错误得出结论。这完全基于哈希顺序。这就是为什么我们称其为HASH set。散列基于输入的长度。尝试使用4个单位数字和4个两位数字。您将得到结果。