List<String> 转换为 Set<String> 的方法
在 Java 中,将 List<String> 转换为 Set<String> 通常用于去重。以下是几种常见实现方式:
方法一:Stream API(推荐,Java 8+)
复制代码
复制代码
List<String> list = Arrays.asList("A", "B", "A", "C");
Set<String> set = list.stream().collect(Collectors.toSet());
完整示例
复制代码
复制代码
import java.util.*;
import java.util.stream.*;
public class Example {
public static void main(String[] args) {
List<String> list = Arrays.asList("苹果", "香蕉", "苹果", "橙子");
// 转换为 Set(去重)
Set<String> set = list.stream()
.collect(Collectors.toSet());
System.out.println(set); // [苹果, 香蕉, 橙子]
}
}
方法二:构造函数(最简洁)
复制代码
复制代码
Set<String> set = new HashSet<>(list);
方法三:传统 for 循环
复制代码
复制代码
Set<String> set = new HashSet<>();
for (String item : list) {
set.add(item);
}
方法四:forEach + Lambda
复制代码
复制代码
Set<String> set = new HashSet<>();
list.forEach(set::add);
方法对比
| 方法 |
代码简洁度 |
性能 |
可读性 |
推荐度 |
| 构造函数 |
⭐⭐⭐⭐⭐ |
最高 |
高 |
✅ 首选 |
| Stream API |
⭐⭐⭐⭐ |
高 |
高 |
✅ 推荐 |
| for 循环 |
⭐⭐⭐ |
最高 |
中 |
兼容性好 |
| forEach |
⭐⭐⭐⭐ |
高 |
高 |
可选 |
进阶处理
1. 指定 Set 类型(LinkedHashSet 保持顺序)
复制代码
复制代码
// Stream + 指定类型
Set<String> set = list.stream()
.collect(Collectors.toCollection(LinkedHashSet::new));
// 构造函数 + 指定类型
Set<String> set = new LinkedHashSet<>(list);
2. 过滤 null 值
复制代码
复制代码
Set<String> set = list.stream()
.filter(Objects::nonNull)
.collect(Collectors.toSet());
3. 过滤空字符串
复制代码
复制代码
Set<String> set = list.stream()
.filter(s -> s != null && !s.isEmpty())
.collect(Collectors.toSet());
4. 转成不可变 Set(Java 10+)
复制代码
复制代码
Set<String> set = list.stream()
.collect(Collectors.toUnmodifiableSet());
// 或 Java 9+
Set<String> set = Set.copyOf(list);
5. 自定义集合大小预估(性能优化)
复制代码
复制代码
// 避免扩容,提升性能
Set<String> set = new HashSet<>((int)(list.size() / 0.75f) + 1);
set.addAll(list);
注意事项
| 问题 |
说明 |
| 空列表处理 |
list 为 null 时会抛 NullPointerException |
| 去重效果 |
Set 会自动去重,重复元素只保留一个 |
| 顺序问题 |
HashSet 无序,LinkedHashSet 保持插入顺序 |
| 线程安全 |
如需线程安全,使用 Collections.synchronizedSet() |
✅ 最佳实践
复制代码
复制代码
// 推荐写法:安全、简洁、高效
Set<String> set = Optional.ofNullable(list)
.orElse(Collections.emptyList())
.stream()
.filter(Objects::nonNull)
.collect(Collectors.toSet());
// 或最简洁写法(确定 list 不为 null 时)
Set<String> set = new HashSet<>(list);
性能测试参考
复制代码
复制代码
// 100 万条数据转换性能对比
List<String> list = IntStream.range(0, 1000000)
.mapToObj(String::valueOf)
.collect(Collectors.toList());
// 构造函数(最快)
long start = System.nanoTime();
Set<String> set1 = new HashSet<>(list);
// 耗时约 50ms
// Stream API
long start2 = System.nanoTime();
Set<String> set2 = list.stream().collect(Collectors.toSet());
// 耗时约 60ms
总结推荐
| 场景 |
推荐方法 |
| 一般场景 |
new HashSet<>(list) |
| 需要过滤 |
list.stream().filter().collect() |
| 保持顺序 |
new LinkedHashSet<>(list) |
| Java 9+ |
Set.copyOf(list) |
| 空安全 |
Optional.ofNullable(list)... |
最简单推荐 :Set<String> set = new HashSet<>(list);