[1,2]
即使hashset未排序,以下代码也会产生输出.
Set set = new HashSet();
set.add(new Integer(2));
set.add(new Integer(1));
System.out.println(set);
Run Code Online (Sandbox Code Playgroud)
这是为什么?
Kar*_*l S 10
编辑:从Java 8及更高版本开始,以下内容不再适用.这证明您不应该依赖未记录的Java行为.
此行为是由几个单独的原因引起的:
HashMap
s和HashSet
s由数组备份因此,如果向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);
}
Run Code Online (Sandbox Code Playgroud)
打印153
.
根据HashSet
文档不能保证任何订单概念,因此您在未来的Java更新中可以很好地改变.
不过,如果你想知道为什么Java的(截至目前)具体实施HashSet
产生你所看到的结果是:这是因为该Integer
值的1
散列到的内部条目表的位置HashMap
是来自之前的位置,它是2
哈希(请注意,a HashSet
实际上由HashMap
具有任意值的a支持).这是有道理的,因为Integer
对象的哈希码只是它的值.
实际上,即使添加更多数字(在一定范围内:条目表的大小默认为16),您也可以看到这一点:
Set<Integer> set = new HashSet<>();
set.add(2);
set.add(1);
set.add(4);
set.add(3);
set.add(0);
System.out.println(set);
Run Code Online (Sandbox Code Playgroud)
[0, 1, 2, 3, 4]
迭代在HashSet
通过循环内部条目表,这意味着项目早在表格中是第一位的发生.