You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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本身不保证任何顺序。

实际问题的正确输出

我们先一步步处理集合中的元素:

  1. Australia 经过swap函数转为New Zealand,取首字母得到N
  2. Japan 保持不变,取首字母得到J
  3. Taiwan 保持不变,取首字母得到T
  4. Cyprus 保持不变,取首字母得到C
  5. Cuba 保持不变,取首字母得到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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 10:25:22