在Java中,可以使用Java 8引入的Stream API来优雅地计算两个列表的交集、并集和差集。下面是使用Stream流的filtercontains等方法来实现这些集合运算的一个详细示例。

示例类定义

首先,我们定义一个简单的Person类来作为我们的数据模型:

 

java

深色版本

1import java.util.Objects;
2
3public class Person {
4    private String name;
5    private int age;
6
7    public Person(String name, int age) {
8        this.name = name;
9        this.age = age;
10    }
11
12    public String getName() {
13        return name;
14    }
15
16    public int getAge() {
17        return age;
18    }
19
20    @Override
21    public boolean equals(Object o) {
22        if (this == o) return true;
23        if (!(o instanceof Person)) return false;
24        Person person = (Person) o;
25        return getAge() == person.getAge() &&
26               getName().equals(person.getName());
27    }
28
29    @Override
30    public int hashCode() {
31        return Objects.hash(getName(), getAge());
32    }
33
34    @Override
35    public String toString() {
36        return "Person{" +
37               "name='" + name + '\'' +
38               ", age=" + age +
39               '}';
40    }
41}

计算交集、并集和差集

接下来,我们将定义一个方法来计算两个List<Person>的交集、并集和差集:

 

java

深色版本

1import java.util.Arrays;
2import java.util.List;
3import java.util.Set;
4import java.util.stream.Collectors;
5
6public class CollectionOperations {
7
8    public static void main(String[] args) {
9        List<Person> list1 = Arrays.asList(
10                new Person("Alice", 25),
11                new Person("Bob", 30),
12                new Person("Charlie", 35),
13                new Person("David", 40)
14        );
15
16        List<Person> list2 = Arrays.asList(
17                new Person("Bob", 30),
18                new Person("Charlie", 35),
19                new Person("Eve", 45),
20                new Person("Frank", 50)
21        );
22
23        // 计算交集
24        List<Person> intersection = computeIntersection(list1, list2);
25        System.out.println("交集: " + intersection);
26
27        // 计算并集
28        List<Person> union = computeUnion(list1, list2);
29        System.out.println("并集: " + union);
30
31        // 计算差集 (list1 - list2)
32        List<Person> difference1 = computeDifference(list1, list2);
33        System.out.println("差集 (list1 - list2): " + difference1);
34
35        // 计算差集 (list2 - list1)
36        List<Person> difference2 = computeDifference(list2, list1);
37        System.out.println("差集 (list2 - list1): " + difference2);
38    }
39
40    public static List<Person> computeIntersection(List<Person> list1, List<Person> list2) {
41        Set<Person> set2 = list2.stream().collect(Collectors.toSet());
42        return list1.stream()
43                   .filter(set2::contains)
44                   .collect(Collectors.toList());
45    }
46
47    public static List<Person> computeUnion(List<Person> list1, List<Person> list2) {
48        Set<Person> set1 = list1.stream().collect(Collectors.toSet());
49        set1.addAll(list2);
50        return set1.stream().collect(Collectors.toList());
51    }
52
53    public static List<Person> computeDifference(List<Person> source, List<Person> toRemove) {
54        Set<Person> removeSet = toRemove.stream().collect(Collectors.toSet());
55        return source.stream()
56                    .filter(person -> !removeSet.contains(person))
57                    .collect(Collectors.toList());
58    }
59}

方法解释

  1. 计算交集 (computeIntersection):

    • list2转换成一个Set,这将有助于提高contains方法的性能。
    • 使用filter方法来过滤list1中的元素,只保留那些在set2中的元素。
  2. 计算并集 (computeUnion):

    • list1转换成一个Set
    • 使用addAll方法将list2中的所有元素添加到set1中,从而实现并集操作。
    • 最后将set1转换回List
  3. 计算差集 (computeDifference):

    • toRemove转换成一个Set
    • 使用filter方法来过滤source中的元素,排除掉那些在removeSet中的元素。

输出结果

当运行上述代码时,你会得到以下输出:

 

深色版本

1交集: [Person{name='Bob', age=30}, Person{name='Charlie', age=35}]
2并集: [Person{name='Alice', age=25}, Person{name='Bob', age=30}, Person{name='Charlie', age=35}, Person{name='David', age=40}, Person{name='Eve', age=45}, Person{name='Frank', age=50}]
3差集 (list1 - list2): [Person{name='Alice', age=25}, Person{name='David', age=40}]
4差集 (list2 - list1): [Person{name='Eve', age=45}, Person{name='Frank', age=50}]

总结

通过使用Java 8的Stream API,你可以以一种简洁且高效的方式来计算两个列表之间的交集、并集和差集。这种方法不仅提高了代码的可读性和可维护性,而且在某些情况下还能提高性能。特别是将一个列表转换为Set可以极大地提高contains方法的效率,尤其是在处理大数据量的时候。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐