Java 常见合并集合几种方式总结(List、Set、Map)
·
Java 提供了多种方式来合并集合(List、Set、Map),不同场景下可选择最合适的方法。以下是常见的合并集合方式的整理:
1. 合并 List
1.1 addAll()
适用场景:直接合并两个 List
特点:修改原集合,无需创建新集合
示例:
List<String> list1 = new ArrayList<>(Arrays.asList("A", "B", "C"));List<String> list2 = Arrays.asList("D", "E");list1.addAll(list2);System.out.println(list1); // [A, B, C, D, E]
1.2 Stream.concat()
适用场景:不修改原集合,返回新 List
特点:流式操作,适用于不可变集合
示例:
List<String> mergedList = Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList());System.out.println(mergedList); // [A, B, C, D, E
1.3 Stream.of() + flatMap()
适用场景:合并多个 List
特点:可同时合并多个 List
示例:
List<String> list3 = Arrays.asList("F", "G");List<String> mergedList = Stream.of(list1, list2, list3).flatMap(Collection::stream).collect(Collectors.toList());System.out.println(mergedList); // [A, B, C, D, E, F, G]
1.4 List.copyOf()
适用场景:创建不可变 List
特点:返回 不可变 集合
示例:
List<String> mergedList = List.copyOf(Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList()));System.out.println(mergedList); // [A, B, C, D, E
2. 合并 Set
2.1 addAll()
适用场景:合并 Set(无重复元素)
示例:
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3));Set<Integer> set2 = new HashSet<>(Arrays.asList(3, 4, 5));set1.addAll(set2);System.out.println(set1); // [1, 2, 3, 4, 5]
2.2 Stream.concat()
适用场景:不修改原集合
示例:
Set<Integer> mergedSet = Stream.concat(set1.stream(), set2.stream()).collect(Collectors.toSet());System.out.println(mergedSet); // [1, 2, 3, 4, 5]
2.3 Stream.of() + flatMap()
适用场景:合并多个 Set
示例:
Set<Integer> set3 = new HashSet<>(Arrays.asList(6, 7));Set<Integer> mergedSet = Stream.of(set1, set2, set3).flatMap(Set::stream).collect(Collectors.toSet());System.out.println(mergedSet); // [1, 2, 3, 4, 5, 6, 7]
3. 合并 Map
3.1 putAll()
适用场景:直接合并 Map
特点:如果 key 存在,后者会覆盖前者
示例:
Map<String, Integer> map1 = new HashMap<>();map1.put("A", 1);map1.put("B", 2);Map<String, Integer> map2 = new HashMap<>();map2.put("B", 3);map2.put("C", 4);map1.putAll(map2);System.out.println(map1); // {A=1, B=3, C=4}
3.2 merge()
适用场景:合并时处理重复 key
特点:可指定 key 处理方式
示例:
map2.forEach((key, value) ->map1.merge(key, value, Integer::sum));System.out.println(map1); // {A=1, B=5, C=4}
3.3 compute()
适用场景:动态计算 key
示例:
map2.forEach((key, value) ->map1.compute(key, (k, v) -> (v == null) ? value : v + value));System.out.println(map1); // {A=1, B=5, C=4}
3.4 Stream API
适用场景:不修改原 Map,生成新 Map
示例:
Map<String, Integer> mergedMap = Stream.of(map1, map2).flatMap(m -> m.entrySet().stream()).collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,Integer::sum));System.out.println(mergedMap); // {A=1, B=5, C=4}
4. 总结
| 数据结构 | 方法 | 适用场景 | 是否修改原集合 |
|---|---|---|---|
| List | addAll() |
直接合并 |
✅ |
Stream.concat() |
不修改原 List |
❌ |
|
Stream.of() + flatMap() |
合并多个 List |
❌ |
|
List.copyOf() |
创建不可变 List |
❌ |
|
| Set | addAll() |
直接合并 |
✅ |
Stream.concat() |
不修改原 Set |
❌ |
|
Stream.of() + flatMap() |
合并多个 Set |
❌ |
|
| Map | putAll() |
后者覆盖前者 |
✅ |
merge() |
合并相同 key |
✅ |
|
compute() |
计算 key 值 |
✅ |
|
Stream API |
不修改原 Map |
❌ |
✅ 修改原集合:适用于直接更新已有集合的场景。
❌ 不修改原集合:适用于函数式编程、不可变集合的场景。
这几种方式适用于不同的开发需求,具体选择哪种方法取决于业务逻辑和性能要求。
更多推荐
所有评论(0)