Set默认是否排序?HashSet输出固定顺序原因及代码题求解
为什么HashSet遍历会得到固定顺序?
我创建了一个按指定顺序添加元素的Set集合:
Set<String> nations = new HashSet<String>(); nations.add("Australia"); nations.add("Japan"); nations.add("Taiwan"); nations.add("Cyprus"); nations.add("Cuba"); nations.add("India");
当我通过如下代码遍历输出时:
for (String s : nations) { System.out.print(s + " "); }
输出顺序始终为:
Cuba Cyprus Japan Taiwan Australia India
据我所知Set默认是不排序的,为何我会得到固定的特定顺序?
实际问题:集合处理后的输出结果判断
以下是实际问题代码:
public static Function<String,String> swap = s -> { if(s.equals("Australia")) return "New Zealand"; else return s; }; Set<String> islandNations = Set.of("Australia", "Japan", "Taiwan", "Cyprus", "Cuba"); islandNations = islandNations.stream() .map(swap) .map(n -> n.substring(0, 1)) .collect(Collectors.toSet()); for(String s : islandNations){ System.out.print(s); }
请从以下选项中选出正确输出结果:
- CTJN
- TJNC
- TCNJ
问题解答
关于HashSet遍历顺序固定的原因
HashSet底层基于哈希表实现,它的遍历顺序由元素的哈希值决定。Java中String的哈希值计算规则是固定的,所以你添加的这些字符串的哈希值不会变化,它们在哈希表中的存储位置相对固定,遍历顺序也就保持一致。但要注意:这不是官方承诺的有序性,一旦元素数量增加导致哈希表扩容、或者更换JDK版本,遍历顺序都可能改变,HashSet本身不保证任何顺序。
实际问题的正确输出
我们先一步步处理集合中的元素:
Australia经过swap函数转为New Zealand,取首字母得到NJapan保持不变,取首字母得到JTaiwan保持不变,取首字母得到TCyprus保持不变,取首字母得到CCuba保持不变,取首字母得到C
Set会自动去重,最终集合中的元素为{C, J, N, T}。Collectors.toSet()默认返回HashSet,其遍历顺序由元素哈希值对应的桶位置决定:
- 字母
C的哈希值是67,对HashSet初始容量16取模结果为67%16=3 - 字母
T的哈希值是84,取模结果为84%16=4 - 字母
J的哈希值是74,取模结果为74%16=10 - 字母
N的哈希值是78,取模结果为78%16=14
HashSet会按桶的编号从小到大遍历,所以输出顺序是C→T→J→N,即CTJN,对应第一个选项。
内容的提问来源于stack exchange,提问作者AmanJ
相关产品推荐
相关产品推荐

