List 转 Set
将 List 转换为 Set 最直接的方法就是使用 Set 的构造函数,这样做的主要目的是去除重复元素,因为 Set 集合中不允许有重复的元素。

使用 HashSet 构造函数(最常用)
HashSet 是最常用的 Set 实现类,它不保证元素的顺序(插入顺序和遍历顺序可能不同)。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ListToSetExample {
public static void main(String[] args) {
// 1. 创建一个包含重复元素的 List
List<String> fruitList = new ArrayList<>(Arrays.asList("apple", "banana", "orange", "apple", "grape"));
System.out.println("原始 List: " + fruitList);
// 2. 使用 HashSet 的构造函数将 List 转换为 Set
// 这会自动去除重复的 "apple"
Set<String> fruitSet = new HashSet<>(fruitList);
System.out.println("转换后的 Set: " + fruitSet);
// 输出可能是: [orange, grape, apple, banana] (顺序不固定)
}
}
使用 LinkedHashSet 构造函数(保留插入顺序)
如果你希望在转换后保留原始 List 的插入顺序,应该使用 LinkedHashSet。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class ListToSetPreserveOrder {
public static void main(String[] args) {
List<String> fruitList = new ArrayList<>(Arrays.asList("apple", "banana", "orange", "apple", "grape"));
System.out.println("原始 List: " + fruitList);
// 使用 LinkedHashSet 的构造函数
Set<String> fruitSet = new LinkedHashSet<>(fruitList);
System.out.println("转换后的 LinkedHashSet: " + fruitSet);
// 输出: [apple, banana, orange, grape] (保留了插入顺序)
}
}
使用 Java 8 Stream API
如果你想在转换的同时进行一些操作(如过滤),可以使用 Stream API。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class ListToSetWithStream {
public static void main(String[] args) {
List<String> fruitList = new ArrayList<>(Arrays.asList("apple", "banana", "orange", "apple", "grape"));
System.out.println("原始 List: " + fruitList);
// 使用 Stream 去重并收集到 HashSet 中
Set<String> fruitSet = fruitList.stream()
.collect(Collectors.toSet());
System.out.println("转换后的 Set (Stream): " + fruitSet);
// 使用 Stream 收集到 LinkedHashSet 中以保留顺序
Set<String> orderedFruitSet = fruitList.stream()
.collect(Collectors.toCollection(LinkedHashSet::new));
System.out.println("转换后的 LinkedHashSet (Stream): " + orderedFruitSet);
}
}
Set 转 List
将 Set 转换为 List 同样简单,通常使用 List 的构造函数,这样做的主要目的是允许重复元素或支持 List 特有的操作(如按索引访问 get(i))。

使用 ArrayList 构造函数(最常用)
这是最直接、最常用的方法。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class SetToListExample {
public static void main(String[] args) {
// 1. 创建一个 Set
Set<String> fruitSet = new HashSet<>(Arrays.asList("apple", "banana", "orange"));
System.out.println("原始 Set: " + fruitSet);
// 2. 使用 ArrayList 的构造函数将 Set 转换为 List
List<String> fruitList = new ArrayList<>(fruitSet);
System.out.println("转换后的 List: " + fruitList);
}
}
使用 Java 8 Stream API
Stream API 提供了另一种灵活的方式。
import java.util.Set;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
public class SetToListWithStream {
public static void main(String[] args) {
Set<String> fruitSet = new HashSet<>(Arrays.asList("apple", "banana", "orange"));
System.out.println("原始 Set: " + fruitSet);
// 使用 Stream 收集到 ArrayList 中
List<String> fruitList = fruitSet.stream()
.collect(Collectors.toList());
System.out.println("转换后的 List (Stream): " + fruitList);
}
}
总结与最佳实践
| 转换方向 | 常用方法 | 目的/特点 | 示例代码 |
|---|---|---|---|
| List → Set | new HashSet<>(list) |
去重,不保证顺序 | Set<String> set = new HashSet<>(myList); |
new LinkedHashSet<>(list) |
去重并保留插入顺序 | Set<String> set = new LinkedHashSet<>(myList); |
|
| Set → List | new ArrayList<>(set) |
允许重复,支持索引访问 | List<String> list = new ArrayList<>(mySet); |
关键注意事项:
-
元素顺序:
- 当你从
List转换到Set时,除了LinkedHashSet,其他Set实现(如HashSet,TreeSet)不会保留原始List的插入顺序。 - 当你从
Set转换到List时,List的顺序取决于原始Set的迭代顺序,对于HashSet,顺序也是不确定的;对于LinkedHashSet,顺序是其插入顺序;对于TreeSet,顺序是其排序顺序。
- 当你从
-
空集合:
- 如果传入的
List或Set是null,使用构造函数会抛出NullPointerException,在转换前最好进行判空处理。List<String> myList = ...; // 可能是 null Set<String> mySet = myList != null ? new HashSet<>(myList) : new HashSet<>();
- 如果传入的
-
性能:
- 使用构造函数进行转换通常是最直接且性能较好的方式,时间复杂度通常是 O(n),n 是集合中的元素数量。
- Stream API 提供了极大的灵活性,特别是在需要结合
filter,map等中间操作时,但对于简单的转换,构造函数更简洁高效。
