在Java里如何遍历HashSet集合_Java去重集合迭代说明

HashSet遍历无序且不支持下标访问,与ArrayList根本不同;需有序用LinkedHashSet,需排序应转List或Stream处理,遍历时删除元素必须用Iterator.remove()。

HashSet 不能保证遍历顺序,且不支持下标访问 —— 这是它和 ArrayList 最根本的区别。如果你只是想“把每个元素拿出来用一遍”,直接用增强 for 或迭代器即可;但若隐含了“需要有序”“要跳过某些元素”“要边遍历边删”等需求,就得特别小心。

用增强 for 循环最简单,但不能删元素

这是日常遍历时最常用的方式,写法简洁,语义清晰:

HashSet set = new HashSet<>();
set.add("apple");
set.add("banana");
set.add("cherry");

for (String item : set) {
    System.out.println(item); // 输出顺序不确定,可能是 banana, apple, cherry
}

⚠️ 注意:循环体内绝对不要调用 set.remove(item),否则会抛 ConcurrentModificationException。HashSet 的迭代器是“快速失败”(fail-fast)的,结构一变就立刻报错。

要用迭代器删除元素,必须用 iterator.remove()

如果逻辑确实需要在遍历时动态剔除某些元素(比如过滤掉空字符串),只能走 Iterator 显式路径:

Iterator it = set.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s == null || s.trim().isEmpty()) {
        it.remove(); // ✅ 唯一安全的删除方式
    }
}
  • it.remove() 是迭代器自己的方法,它会同步更新内部的 modCount,避免异常
  • 不能写成 set.remove(s),哪怕你刚从 it.next() 拿到这个 s
  • 每个 it.next() 后最多调用一次 it.remove(),重复调用会抛 IllegalStateException

想按插入顺序遍历?换 LinkedHashSet

标准 HashSet 底层是哈希表 + 链表(JDK 8+ 还可能转红黑树),但链表只用于解决哈希冲突,不维护插入顺序。如果你需要“先加的先出来”,必须显式选型:

Set orderedSet = new LinkedHashSet<>();
orderedSet.add("first");
orderedSet.add("second");
orderedSet.add("third");

for (String s : orderedSet) {
    System

.out.println(s); // 一定输出 first → second → third }

LinkedHashSet 保留插入顺序,遍历性能略低于 HashSet(多维护一条双向链表),内存占用稍高,但绝大多数业务场景可忽略。

需要排序遍历?别硬遍历 HashSet,先转再处理

HashSet 本身无序,也不提供 sort() 方法。如果最终要按字母、数字或自定义规则排序,推荐做法是:把数据抽出来,丢给有序结构处理:

// 方案1:转为 List 后排序
List sortedList = new ArrayList<>(set);
Collections.sort(sortedList);

// 方案2:一步到位(Java 8+)
List sorted = set.stream()
    .sorted(String::compareTo)
    .collect(Collectors.toList());

// 方案3:如果只是临时遍历,用 TreeSet(注意:会去重+排序,但改变原始集合语义)
TreeSet treeSet = new TreeSet<>(set); // 自然序

⚠️ 别写 for (int i = 0; i —— HashSet 没有 get(i),编译不过。

真正容易被忽略的是:你以为“遍历 HashSet 就是拿数据”,但实际中往往混着“顺序要求”“并发修改”“空值处理”一起出现。先确认你的场景到底要什么,再选容器和遍历方式,比硬套 for 循环更省调试时间。