Java 中查找两个List之间的差异

List 是 Java 中常见的数据结构,有时,我们需要比较两个 List ,并找出其中相同或不同的部分。

数据分析

下面给出了一个包含重复数据的 list:

List<String> list1 = Arrays.asList("A", "B", "C", "D", "D");
List<String> list2 = Arrays.asList( "C", "D", "E", "F", "E");

现在我们需要得到的数据为:

  • List1 特有部分 [A, B]
  • List2 特有部分 [E, F]
  • List1 共有部分 [C, D, D]

实现方案

下面用多个实现思路编码。

removeAll

我们可以创建一个列表的副本,然后使用List方法removeAll()删除与另一个列表共有的所有元素:

private static void remove(List<String> list1,List<String> list2){
    List<String> tmp = new ArrayList<>(list1);
    tmp.removeAll(list2);
    System.out.println(tmp);
}
[A, B]

上面是获取 List1 中特有部分,如果想获取 List2 中特有部分,只需要调换一下参数顺序即可。

如果想找到两个列表之间的共同元素,可以使用 List 的 retainAll() 方法。

private static void retain(List<String> list1,List<String> list2){
    List<String> tmp = new ArrayList<>(list1);
    tmp.retainAll(list2);
    System.out.println(tmp);
}
[C, D, D]

filter

Java Stream API 中提供的 filter 可以用于数据过滤:

获取 List1 中共有部分:

private static void filter(List<String> list1,List<String> list2){
    List<String> result = list1.stream()
        .filter(list2::contains)
        .collect(Collectors.toList());
    System.out.println(result);
}
[C, D, D]

如果想把其中重复的去掉,一个简单的方式是生成 Set:

private static void filter(List<String> list1,List<String> list2){
    Set<String> result = list1.stream()
        .filter(s -> list2.contains(s))
        .collect(Collectors.toSet());
    System.out.println(result);
}
[C, D]

获取 List1 中特有部分:

private static void filter(List<String> list1,List<String> list2){
    List<String> result = list1.stream()
        .filter(s -> !list2.contains(s))
        .collect(Collectors.toList());
    System.out.println(result);
}
[A, B]

差别仅仅是一个感叹号 !

标签: