- List (列表): 有序、可重复,允许存储多个
null值。ArrayList,LinkedList。 - Set (集合): 无序(
HashSet)、不重复,只允许存储一个null值。HashSet,TreeSet。
转换的关键在于利用它们的构造函数或Java 8 Stream API。

核心转换方法
List 转 Set
这是最常见的转换,通常目的是为了去重。
使用 Set 的构造函数(最直接)
这是最简单、最常用的方法,直接使用 Set 的实现类(如 HashSet)的构造函数,该构造函数接受一个 Collection(List 实现了 Collection)作为参数。
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"));
// 2. 使用 HashSet 的构造函数将 List 转换为 Set
// Set 的特性会自动去除重复的 "apple"
Set<String> fruitSet = new HashSet<>(fruitList);
// 3. 打印结果
System.out.println("原始 List: " + fruitList); // [apple, banana, orange, apple, grape]
System.out.println("转换后的 Set: " + fruitSet); // [orange, grape, apple, banana] (顺序可能不同)
}
}
特点:
- 优点: 代码简洁,一行搞定。
- 缺点: 默认使用
HashSet,无法保证元素的顺序,如果你需要保持顺序,应该使用LinkedHashSet。
使用 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 ListToSetStreamExample {
public static void main(String[] args) {
List<String> fruitList = new ArrayList<>(Arrays.asList("apple", "banana", "orange", "apple", "grape"));
// 使用 Stream 的 collect 方法将 List 转换为 Set
Set<String> fruitSet = fruitList.stream()
.collect(Collectors.toSet());
System.out.println("原始 List: " + fruitList);
System.out.println("转换后的 Set: " + fruitSet); // 顺序可能不同
}
}
特点:
- 优点: 非常灵活,可以在转换前进行过滤、映射等操作。
- 缺点: 代码稍显冗长,但对于复杂场景非常有用。
保持顺序的转换(使用 LinkedHashSet)
如果你希望转换后的 Set 仍然保留 List 的原始插入顺序,应该使用 LinkedHashSet。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class ListToOrderedSetExample {
public static void main(String[] args) {
List<String> fruitList = new ArrayList<>(Arrays.asList("apple", "banana", "orange", "apple", "grape"));
// 使用 LinkedHashSet 的构造函数来保持顺序
Set<String> orderedFruitSet = new LinkedHashSet<>(fruitList);
System.out.println("原始 List: " + fruitList);
System.out.println("转换后的有序 Set: " + orderedFruitSet); // [apple, banana, orange, grape]
}
}
Set 转 List
转换的目的是为了获得有序的列表,或者允许重复操作。
使用 List 的构造函数(最直接)
与 List 转 Set 类似,直接使用 List 的实现类(如 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"));
// 2. 使用 ArrayList 的构造函数将 Set 转换为 List
List<String> fruitList = new ArrayList<>(fruitSet);
// 3. 打印结果
System.out.println("原始 Set: " + fruitSet); // [orange, apple, banana] (顺序可能不同)
System.out.println("转换后的 List: " + fruitList); // [orange, apple, banana] (顺序与 Set 一致)
}
}
特点:
- 优点: 代码简洁,直接转换。
- 缺点: 转换后的
List的顺序取决于Set的具体实现(HashSet无序,LinkedHashSet有序)。
使用 Java 8 Stream API(更灵活)
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class SetToListStreamExample {
public static void main(String[] args) {
Set<String> fruitSet = new HashSet<>(Arrays.asList("apple", "banana", "orange"));
// 使用 Stream 的 collect 方法将 Set 转换为 List
List<String> fruitList = fruitSet.stream()
.collect(Collectors.toList());
System.out.println("原始 Set: " + fruitSet);
System.out.println("转换后的 List: " + fruitList);
}
}
特点:
- 优点: 同样非常灵活,可以在转换前对元素进行处理。
总结与对比
| 转换方向 | 方法 | 示例代码 | 特点 |
|---|---|---|---|
| List → Set | 构造函数 | Set<T> set = new HashSet<>(list); |
最常用,简洁,默认去重,不保证顺序。 |
| Stream API | Set<T> set = list.stream().collect(Collectors.toSet()); |
灵活,可链式操作,默认去重,不保证顺序。 | |
| 保持顺序 | Set<T> set = new LinkedHashSet<>(list); |
使用 LinkedHashSet,去重且保持插入顺序。 |
|
| Set → List | 构造函数 | List<T> list = new ArrayList<>(set); |
最常用,简洁,将 Set 的元素放入 List。 |
| Stream API | List<T> list = set.stream().collect(Collectors.toList()); |
灵活,可链式操作。 |
最佳实践建议
-
简单转换:如果只是简单地、一次性地在
List和Set之间转换,直接使用构造函数 是最清晰、最高效的选择。List转Set去重:new HashSet<>(myList)Set转List:new ArrayList<>(mySet)
-
需要顺序:
List转Set后需要保持原始顺序,务必使用new LinkedHashSet<>(myList)。 -
复杂处理:如果转换过程中需要包含过滤、映射、条件判断等复杂逻辑,或者代码风格倾向于函数式编程,那么使用 Java 8 Stream API 是更好的选择。
希望这份详细的解释能帮助你完全理解 Java 中 List 和 Set 的转换!
