在Java开发中,比较两个List的内容是否一致是高频需求,很多初学者会直接用==判断,实际上这种方式比较的是两个List对象的引用地址,而非内容,因此无法得到正确的结果。要实现内容层面的比较,需要根据是否要求元素顺序一致选择不同的方案。

一、要求元素顺序一致时的比较方法
1. 使用List自带的equals方法
Java中的List接口已经重写了equals方法,其判断逻辑是:两个List大小相同,且对应位置的元素通过equals方法比较都相等,就认为两个List相等。这是最简便的顺序一致场景下的比较方式。
示例代码如下:
import java.util.ArrayList;
import java.util.List;
public class ListCompareDemo {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("apple");
list1.add("banana");
list1.add("orange");
List<String> list2 = new ArrayList<>();
list2.add("apple");
list2.add("banana");
list2.add("orange");
List<String> list3 = new ArrayList<>();
list3.add("apple");
list3.add("orange");
list3.add("banana");
// 比较list1和list2,顺序一致内容相同
boolean result1 = list1.equals(list2);
System.out.println("list1和list2是否一致:" + result1); // 输出true
// 比较list1和list3,顺序不同内容相同
boolean result2 = list1.equals(list3);
System.out.println("list1和list3是否一致:" + result2); // 输出false
}
}
需要注意的是,List中的元素必须正确实现equals方法,否则即使内容相同,equals比较也可能返回false。比如自定义对象如果没有重写equals方法,会使用Object类的默认equals实现,也就是比较引用地址,导致结果不符合预期。
2. 遍历元素逐一比较
如果不想依赖List的equals方法,也可以手动遍历两个List的元素逐一对比,这种方式可以更灵活地添加自定义的比较逻辑。
示例代码如下:
import java.util.ArrayList;
import java.util.List;
public class ListCompareDemo2 {
public static boolean compareListInOrder(List<String> listA, List<String> listB) {
// 先判断大小是否相同
if (listA.size() != listB.size()) {
return false;
}
// 遍历对应位置元素比较
for (int i = 0; i < listA.size(); i++) {
String eleA = listA.get(i);
String eleB = listB.get(i);
// 处理元素为null的情况
if (eleA == null && eleB == null) {
continue;
}
if (eleA == null || eleB == null) {
return false;
}
if (!eleA.equals(eleB)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("apple");
list1.add(null);
list1.add("orange");
List<String> list2 = new ArrayList<>();
list2.add("apple");
list2.add(null);
list2.add("orange");
System.out.println("两个List是否一致:" + compareListInOrder(list1, list2)); // 输出true
}
}
二、不要求元素顺序一致时的比较方法
如果只需要判断两个List包含的元素完全相同,不关心元素的排列顺序,就需要先对List进行排序,再使用equals比较,或者使用集合的containsAll方法配合大小判断。
1. 排序后使用equals比较
这种方式适合元素可以排序的场景,先对两个List排序,再调用equals方法比较,排序后顺序一致,就能得到正确的结果。
示例代码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ListCompareUnorderedDemo {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("apple");
list1.add("banana");
list1.add("orange");
List<String> list2 = new ArrayList<>();
list2.add("orange");
list2.add("apple");
list2.add("banana");
// 复制两个List避免修改原集合
List<String> copy1 = new ArrayList<>(list1);
List<String> copy2 = new ArrayList<>(list2);
// 排序
Collections.sort(copy1);
Collections.sort(copy2);
// 比较
boolean result = copy1.equals(copy2);
System.out.println("两个List元素是否完全相同:" + result); // 输出true
}
}
这种方式的缺点是会修改原List的顺序,因此需要先复制集合再排序,如果List数据量很大,排序会有一定的性能开销。
2. 使用containsAll配合大小判断
这种方式不需要排序,先判断两个List的大小是否相同,再判断其中一个List是否包含另一个List的所有元素,如果都满足则认为内容一致。
示例代码如下:
import java.util.ArrayList;
import java.util.List;
public class ListCompareUnorderedDemo2 {
public static boolean compareListUnordered(List<String> listA, List<String> listB) {
// 先判断大小是否相同
if (listA.size() != listB.size()) {
return false;
}
// 判断listA是否包含listB的所有元素
return listA.containsAll(listB);
}
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("apple");
list1.add("banana");
list1.add("orange");
List<String> list2 = new ArrayList<>();
list2.add("orange");
list2.add("apple");
list2.add("banana");
System.out.println("两个List元素是否完全相同:" + compareListUnordered(list1, list2)); // 输出true
}
}
这种方式的性能比排序方式更好,但是需要注意,如果List中存在重复元素,containsAll方法可能会出现判断偏差。比如listA是["a","a","b"],listB是["a","b","b"],两者大小都是3,listA.containsAll(listB)会返回true,listB.containsAll(listA)也会返回true,但实际上两个List的元素并不完全相同。因此这种方式只适合List中没有重复元素的场景。
三、不同场景的方法选择建议
可以根据实际需求选择合适的比较方式:
- 如果要求元素顺序一致,优先使用List自带的
equals方法,代码简洁且性能较好 - 如果要求元素顺序一致且需要自定义比较逻辑,可以选择遍历逐一比较的方式
- 如果不要求顺序且List中没有重复元素,优先使用containsAll配合大小判断的方式,性能更优
- 如果不要求顺序且List中可能有重复元素,建议先排序再使用equals比较,确保结果准确
另外需要注意,无论使用哪种方式,List中的元素如果是自定义对象,都需要正确实现equals方法和hashCode方法,否则会导致比较结果不符合预期。