比较两个 List<String>
是否相等
1. 问题描述
在 Java 中,我们经常需要比较两个 List<String>
是否相等。但不同的场景下,可能会有不同的比较方式:
- 是否要求顺序一致?
- 是否允许重复元素?
- 是否完全忽略顺序?
2. 错误示例
下面是一个错误的实现,分析其问题:
public boolean equalsList(List<String> list1, List<String> list2){
// null 情况
if ((list1 == null && list2 != null) || (list1 != null && list2 == null)) {
return false;
}
// 大小比较 - 逻辑错误
if (list1.size() == list2.size) { // ❌ list1.size 不是方法,应该是 list1.size()
return true; // ❌ 这样会导致内容不同但长度相同的列表被认为相等
}
if (list1.size() != list2.size()) {
return false;
}
// 转换为数组并排序
String[] arr1 = list1.toArray(new String[0]);
String[] arr2 = list2.toArray(new String[0]);
Arrays.sort(arr1);
Arrays.sort(arr1); // ❌ 这里应该是 Arrays.sort(arr2);
return Arrays.equals(arr1, arr2);
}
错误点分析:
- 拼写错误:
list1.size
应该是list1.size()
。 - 逻辑错误:
if (list1.size() == list2.size) return true;
直接比较长度并返回true
是错误的。 - 数组排序错误:
Arrays.sort(arr1);
写了两次,arr2
没有排序。
3. 正确实现方式
方式 1:直接使用 List.equals()
(要求顺序相同)
如果列表的元素顺序必须相同,可以直接使用 equals()
方法:
public boolean equalsList(List<String> list1, List<String> list2) {
return Objects.equals(list1, list2);
}
✅ 优点:
- 代码简洁,直接调用
List.equals()
方法。 Objects.equals()
可以处理null
情况。
⚠️ 缺点:
- 顺序必须一致,否则会返回
false
。
方式 2:忽略顺序,但不考虑重复元素(使用 Set
)
如果不考虑顺序,但也不关心重复,可以转换为 Set
进行比较:
public boolean equalsList(List<String> list1, List<String> list2) {
if (list1 == null || list2 == null) {
return list1 == list2;
}
return new HashSet<>(list1).equals(new HashSet<>(list2));
}
✅ 优点:
- 忽略顺序,即
{a, b, c}
和{c, a, b}
认为是相等的。
⚠️ 缺点:
- 会忽略重复元素,即
{a, a, b}
和{a, b}
会被认为相等。
方式 3:忽略顺序,但考虑重复元素(排序+比较)
如果不考虑顺序,但仍然区分重复元素,可以先排序再进行比较:
public boolean equalsList(List<String> list1, List<String> list2) {
if (list1 == null || list2 == null) {
return list1 == list2;
}
if (list1.size() != list2.size()) {
return false;
}
List<String> sortedList1 = new ArrayList<>(list1);
List<String> sortedList2 = new ArrayList<>(list2);
Collections.sort(sortedList1);
Collections.sort(sortedList2);
return sortedList1.equals(sortedList2);
}
✅ 优点:
- 忽略顺序,但不会忽略重复元素。
⚠️ 缺点:
- 需要额外的排序操作,性能可能稍低。
4. 三种方法对比
方法 | 是否考虑顺序 | 是否考虑重复 | 适用场景 |
---|---|---|---|
list1.equals(list2) | ✅ 是 | ✅ 是 | 顺序必须相同,内容相同 |
new HashSet<>(list1).equals(new HashSet<>(list2)) | ❌ 否 | ❌ 否 | 仅关心元素是否相同,不关心顺序和重复 |
排序后再 equals() | ❌ 否 | ✅ 是 | 无序列表,但重复元素数量要相同 |
5. 结论
- 如果顺序必须相同 →
list1.equals(list2)
- 如果顺序无关,但不考虑重复 → 使用
Set
进行比较。 - 如果顺序无关,但要考虑重复 → 排序后再比较。