杰瑞科技汇

Java遍历HashSet有几种常用方法?

下面我将介绍几种最常用和最推荐的遍历 HashSet 的方法,并提供详细的代码示例和解释。

Java遍历HashSet有几种常用方法?-图1
(图片来源网络,侵删)

准备工作:创建一个示例 HashSet

我们创建一个 HashSet 并添加一些元素,以便在后续的示例中使用。

import java.util.HashSet;
import java.util.Set;
public class HashSetIterationExample {
    public static void main(String[] args) {
        // 创建一个 HashSet 并添加一些水果
        Set<String> fruits = new HashSet<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Orange");
        fruits.add("Grape");
        // 重复添加 "Apple",但 Set 会保证唯一性
        fruits.add("Apple");
        System.out.println("原始 HashSet 内容: " + fruits);
        // 注意:输出顺序可能与添加顺序不同, [Orange, Apple, Grape, Banana]
    }
}

使用增强 for 循环 (For-Each Loop)

这是最常用、最简洁、最推荐的方式,它适用于任何实现了 Iterable 接口的集合,包括 HashSet

语法:

for (Type element : set) {
    // 处理 element
}

示例:

Java遍历HashSet有几种常用方法?-图2
(图片来源网络,侵删)
System.out.println("\n--- 使用增强 for 循环遍历 ---");
for (String fruit : fruits) {
    System.out.println("水果: " + fruit);
}

优点:

  • 代码简洁易读:语法非常清晰,没有冗余的代码。
  • 性能好:对于 HashSet 其内部迭代器的效率很高。
  • 安全:在遍历过程中,如果尝试调用 set.remove() 方法,会抛出 ConcurrentModificationException 异常,这可以防止在迭代时意外修改集合,保证了遍历的安全性。

缺点:

  • 无法获取索引:如果你需要在遍历时获取元素的索引,这种方法不适用。
  • 不能在遍历中安全地删除元素:如上所述,直接调用 remove() 会抛出异常,如果需要在遍历时删除元素,应该使用方法三或方法四。

使用迭代器 (Iterator)

这是最传统、最底层的方式,也是 Java Collections Framework 提供的标准遍历机制,它提供了在遍历过程中安全地删除元素的能力。

语法:

Java遍历HashSet有几种常用方法?-图3
(图片来源网络,侵删)
Iterator<Type> iterator = set.iterator();
while (iterator.hasNext()) {
    Type element = iterator.next();
    // 处理 element
}

示例:

System.out.println("\n--- 使用 Iterator 遍历 ---");
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
    String fruit = iterator.next();
    System.out.println("水果: " + fruit);
}

优点:

  • 功能强大:可以安全地在遍历过程中删除元素(通过调用 iterator.remove())。
  • 通用性:是所有集合类通用的遍历方式。

缺点:

  • 代码稍显冗长:相比增强 for 循环,需要多写几行代码。

在遍历中安全地删除元素

Iterator 的一个核心优势是它的 remove() 方法,这个方法会删除上次调用 next() 方法返回的元素。

示例:删除长度小于 5 的水果

System.out.println("\n--- 使用 Iterator 在遍历中安全删除元素 ---");
// 注意:这里我们创建一个新的 HashSet 来演示,避免混淆
Set<String> fruitsForRemoval = new HashSet<>(fruits);
Iterator<String> removalIterator = fruitsForRemoval.iterator();
while (removalIterator.hasNext()) {
    String fruit = removalIterator.next();
    if (fruit.length() < 5) {
        removalIterator.remove(); // 安全地删除当前元素
        System.out.println("已删除: " + fruit);
    }
}
System.out.println("删除后的 HashSet 内容: " + fruitsForRemoval);

错误示范 (会抛出异常):

// for (String fruit : fruitsForRemoval) {
//     if (fruit.length() < 5) {
//         fruitsForRemoval.remove(fruit); // ConcurrentModificationException
//     }
// }

使用 Java 8+ 的 Stream API (forEach)

如果你使用的是 Java 8 或更高版本,可以使用 Stream API 来遍历集合,这种方式非常适合进行函数式编程风格的操作,如过滤、映射等。

语法:

set.stream().forEach(element -> {
    // 处理 element
});

示例:

System.out.println("\n--- 使用 Java 8 Stream API 的 forEach 遍历 ---");
fruits.stream().forEach(fruit -> System.out.println("水果: " + fruit));

你也可以使用方法引用(Method Reference)让代码更简洁:

fruits.forEach(System.out::println);

优点:

  • 函数式编程风格:非常适合与链式操作(如 filter, map, collect)结合使用。
  • 并行处理:可以轻松地通过 parallelStream() 实现并行遍历,以提高大数据量下的处理速度。

缺点:

  • 性能开销:对于简单的遍历,创建 Stream 会带来轻微的性能开销。
  • 不能直接删除元素forEach 内部也是一个“外部迭代器”,直接调用集合的 remove() 方法同样会抛出 ConcurrentModificationException,如果你想在 Stream 操作中删除元素,通常需要先收集到一个新的集合中。

使用 Java 8+ 的 removeIf

如果你需要在遍历时根据条件删除元素,removeIf 是最直接、最优雅的方法,它内部就是使用迭代器实现的,所以是线程安全的。

语法:

set.removeIf(element -> condition);

示例:删除所有以 "A" 开头的水果(不区分大小写)

System.out.println("\n--- 使用 Java 8 removeIf 删除元素 ---");
System.out.println("删除前的内容: " + fruits);
fruits.removeIf(fruit -> fruit.toUpperCase().startsWith("A"));
System.out.println("删除以 'A' 开头的水果后: " + fruits);

优点:

  • 代码极其简洁:一行代码就能完成条件删除。
  • 安全高效:内部使用迭代器,保证了遍历和删除的安全性。

缺点:

  • 功能单一:仅用于删除元素,不能用于其他处理。

总结与选择建议

方法 优点 缺点 适用场景
增强 for 循环 简洁、易读、性能好 无法获取索引,遍历时不能安全删除 绝大多数日常遍历场景,首选。
Iterator 功能强大,可安全删除元素 代码稍显冗长 需要在遍历过程中安全地删除元素时。
Stream API 函数式风格,支持并行和链式操作 有性能开销,遍历时不能直接删除 需要进行复杂的函数式操作(过滤、映射等)或并行处理时。
removeIf 代码极其简洁,专为条件删除设计 功能单一 仅需根据条件批量删除元素时。

  • 只是想简单地读取每一个元素:用 增强 for 循环
  • 想在读的时候顺便删掉一些元素:用 Iterator 或者 Java 8+ 的 removeIf
  • 想对元素进行复杂的处理(比如筛选、转换):用 Stream API
分享:
扫描分享到社交APP
上一篇
下一篇