引言:为什么要在 Java 中合并列表以及如何避免混淆
想象一下:你有两个任务列表——“紧急”和“重要”。或者两个客户列表——来自上个月的数据库和本月的数据库。为了将它们作为一个整体来处理,你需要合并它们。在 Java 中,这个任务非常常见,以至于 Stack Overflow 上的问题 “How do I join two lists in Java?” 获得了数千次浏览。这并非偶然:对于新手来说,合并列表经常引起混淆——要么出现编译错误,要么列表变得不可修改,要么数据丢失。
在本文中,我们将介绍 5 种经过验证的 Java 合并两个列表的方法——从经典的 addAll 到优雅的 Stream API。您将了解如何针对不同情况选择合适的方法,如何避免陷阱,并编写快速且可预测的代码。开始吧!
方法 1:经典的 addAll——简单可靠
最直接的方法是使用 Collection 接口中的 addAll() 方法。它将一个集合中的所有元素添加到另一个集合中。听起来很完美,但有一个注意事项:它会修改原始列表。如果您需要保持原始列表不变,请创建一个新列表。
示例:合并并保留原始列表
import java.util.ArrayList;import java.util.List;
public class JoinListsExample { public static void main(String[] args) { List<String> listA = new ArrayList<>(List.of("Java", "Python", "C++")); List<String> listB = new ArrayList<>(List.of("JavaScript", "Go", "Rust"));
// 创建一个新列表,并将两个列表都添加进去 List<String> mergedList = new ArrayList<>(listA); mergedList.addAll(listB);
System.out.println(mergedList); // [Java, Python, C++, JavaScript, Go, Rust] // 原始列表未改变 }}优点:直观易懂,适用于任何 List 类型,不需要 Java 8+。
缺点:如果不创建新列表,会修改原始列表;不支持惰性计算。
方法 2:Stream API——现代且灵活
如果您使用 Java 8 或更高版本,Stream API 提供了一种优雅的合并列表方式。它不会修改原始数据,并且可以轻松与其他操作(如过滤、排序、转换)结合使用。
通过 Stream.concat 进行基本合并
import java.util.List;import java.util.stream.Collectors;import java.util.stream.Stream;
public class StreamJoinExample { public static void main(String[] args) { List<String> listA = List.of("红色", "绿色", "蓝色"); List<String> listB = List.of("黄色", "紫色");
List<String> mergedList = Stream.concat(listA.stream(), listB.stream()) .collect(Collectors.toList());
System.out.println(mergedList); // [红色, 绿色, 蓝色, 黄色, 紫色] }}带过滤和排序的合并
假设需要合并两个数字列表,只保留偶数并按降序排序:
import java.util.List;import java.util.Comparator;import java.util.stream.Collectors;import java.util.stream.Stream;
public class StreamAdvancedJoin { public static void main(String[] args) { List<Integer> listA = List.of(5, 2, 8, 1); List<Integer> listB = List.of(7, 4, 9, 3);
List<Integer> result = Stream.concat(listA.stream(), listB.stream()) .filter(n -> n % 2 == 0) // 仅偶数 .sorted(Comparator.reverseOrder()) .collect(C