章
目
录
学习在Java中比较两个ArrayList以查找它们是否包含相同的元素。如果这两个列表不相等,我们将找到它们之间的差异。我们还将学习如何找到每个列表中的共同项和不同项。
请注意,两个列表之间的差异等于第三个列表,其中包含了额外的元素或缺少的元素。
1.比较两个列表是否相等
1.1. 先排序再比较
以下的Java程序用于测试给定的两个列表是否相等。为了测试它们是否相等,我们需要对两个列表进行排序,然后使用equals()方法比较它们。
List.equals()方法仅在以下情况下返回true:
- 两个列表的大小相同
- 它们包含完全相同顺序的相同元素
ArrayList<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
ArrayList<String> equalList = new ArrayList<>(Arrays.asList("c", "b", "a"));
ArrayList<String> diffList = new ArrayList<>(Arrays.asList("a", "b", "d")); //c and d are changed
Collections.sort(list);
Collections.sort(equalList);
Assertions.assertTrue(list.equals(equalList));
Collections.sort(diffList);
Assertions.assertFalse(list.equals(diffList));
1.2. 使用Commons Collections
如果项目中依赖于commons-collections4,我们可以使用CollectionUtils.isEqualCollection() API。这个API会比较两个列表的项,忽略它们的顺序。
boolean result = CollectionUtils.isEqualCollection(firstList, secondList);
1.3. 在单元测试中比较列表
如果在单元测试中检查列表的相等性,可以考虑使用Matchers.containsInAnyOrder()。
Assertions.assertThat(firstList, Matchers.containsInAnyOrder( secondList.toArray() ));
2.比较两个列表- 查找额外的元素
在以下示例中,我们将找到存在于list1中但不在list2中的项。
2.1. 纯Java
如果两个ArrayList不相等,且我们想找出第一个列表中相对于第二个列表的额外元素,可以使用removeAll()方法。它会从第一个列表中移除第二个列表中的所有元素,只留下第一个列表中的额外元素。
ArrayList<String> listOne = new ArrayList<>(Arrays.asList("a", "b", "c", "d"));
ArrayList<String> listTwo = new ArrayList<>(Arrays.asList("a", "b", "e", "f"));
//listOne中额外项
listOne.removeAll(listTwo);
System.out.println(listOne); //[c, d]
2.2. 使用Stream API
我们可以迭代第一个列表的列表项,并在第二个列表中搜索所有元素。如果该元素存在于第二个列表中,就从第一个列表中将其移除。在流操作之后,将这些项收集到一个新的列表中。
List<String> listOfAdditionalItems = listOne.stream()
.filter(item -> !listTwo.contains(item))
.toList();
Assertions.assertTrue(CollectionUtils.isEqualCollection(List.of("c", "d"), listOfAdditionalItems));
2.3. 使用CollectionUtils.removeAll()
CollectionUtils.removeAll(list1, list2) 返回一个包含list1中不在list2中的所有元素的集合。CollectionUtils类是Apache commons-collection4库的一部分。
List<String> listOfAdditionalItems = (List<String>) CollectionUtils.removeAll(listOne, listTwo);
Assertions.assertTrue(CollectionUtils.isEqualCollection(List.of("c", "d"), listOfAdditionalItems));
3.比较两个列表 – 查找缺失的项
要获取在list1中缺失但在list2中存在的元素,可以反转上一节中的解决方案。
纯Java的解决方案如下:
ArrayList<String> listOne = new ArrayList<>(Arrays.asList("a", "b", "c", "d"));
ArrayList<String> listTwo = new ArrayList<>(Arrays.asList("a", "b", "e", "f"));
//missing items in listOne
listTwo.removeAll(listOne);
System.out.println(listTwo); //[e, f]
使用Stream API的解决方案如下:
List<String> listOfMissingItems = listTwo.stream()
.filter(item -> !listOne.contains(item))
.toList();
Assertions.assertTrue(CollectionUtils.isEqualCollection(List.of("e", "f"), listOfMissingItems));
同样,将List的顺序反转后使用CollectionUtils.removeAll()。
List<String> listOfMissingItems = (List<String>) CollectionUtils.removeAll(listTwo, listOne);
Assertions.assertTrue(CollectionUtils.isEqualCollection(List.of("e", "f"), listOfMissingItems));
4.比较两个列表 – 查找共同的项
要查找两个ArrayList中的共同元素,可以使用List.retainAll()方法。这个方法仅保留在该列表中的元素,这些元素包含在作为方法参数传递的指定ArrayList中。
ArrayList<String> listOne = new ArrayList<>(Arrays.asList("a", "b", "c", "d"));
ArrayList<String> listTwo = new ArrayList<>(Arrays.asList("a", "b", "e", "f"));
//listOne和listTwo中的共同项。
listOne.retainAll(listTwo); //[a, b]
我们也可以使用Stream API来查找所有共同的项,如下所示:
List<String> listOfCommonItems = listOne.stream()
.filter(item -> listTwo.contains(item))
.toList();
Assertions.assertTrue(CollectionUtils.isEqualCollection(List.of("a", "b"), listOfCommonItems));
此外,还可以使用CollectionUtils.intersection()方法,它返回两个列表中的共同元素。
List<String> listOfCommonItems = (List<String>) CollectionUtils.intersection(listTwo, listOne);
Assertions.assertTrue(CollectionUtils.isEqualCollection(List.of("a", "b"), listOfCommonItems));
以上就是Java中比较两个List列表的全部内容。