在Java中,可以使用Java 8及以后版本的Stream API来高效地计算两个List
之间的差集、并集和交集。下面我将通过具体的例子来展示如何实现这些集合操作。
示例类定义
首先,我们定义一个简单的Person
类来作为我们的数据模型:
深色版本
1public class Person {
2 private String name;
3 private int age;
4
5 public Person(String name, int age) {
6 this.name = name;
7 this.age = age;
8 }
9
10 public String getName() {
11 return name;
12 }
13
14 public int getAge() {
15 return age;
16 }
17
18 @Override
19 public boolean equals(Object o) {
20 if (this == o) return true;
21 if (!(o instanceof Person)) return false;
22 Person person = (Person) o;
23 return getAge() == person.getAge() &&
24 getName().equals(person.getName());
25 }
26
27 @Override
28 public int hashCode() {
29 return Objects.hash(getName(), getAge());
30 }
31
32 @Override
33 public String toString() {
34 return "Person{" +
35 "name='" + name + '\'' +
36 ", age=" + age +
37 '}';
38 }
39}
计算交集、并集和差集
接下来,我们将定义一个方法来计算两个List<Person>
的交集、并集和差集:
深色版本
1import java.util.*;
2import java.util.stream.Collectors;
3
4public class CollectionOperations {
5
6 public static void main(String[] args) {
7 List<Person> list1 = Arrays.asList(
8 new Person("Alice", 25),
9 new Person("Bob", 30),
10 new Person("Charlie", 35),
11 new Person("David", 40)
12 );
13
14 List<Person> list2 = Arrays.asList(
15 new Person("Bob", 30),
16 new Person("Charlie", 35),
17 new Person("Eve", 45),
18 new Person("Frank", 50)
19 );
20
21 // 计算交集
22 List<Person> intersection = computeIntersection(list1, list2);
23 System.out.println("交集: " + intersection);
24
25 // 计算并集
26 List<Person> union = computeUnion(list1, list2);
27 System.out.println("并集: " + union);
28
29 // 计算差集 (list1 - list2)
30 List<Person> difference1 = computeDifference(list1, list2);
31 System.out.println("差集 (list1 - list2): " + difference1);
32
33 // 计算差集 (list2 - list1)
34 List<Person> difference2 = computeDifference(list2, list1);
35 System.out.println("差集 (list2 - list1): " + difference2);
36 }
37
38 public static List<Person> computeIntersection(List<Person> list1, List<Person> list2) {
39 Set<Person> set1 = new HashSet<>(list1);
40 Set<Person> set2 = new HashSet<>(list2);
41
42 set1.retainAll(set2);
43 return new ArrayList<>(set1);
44 }
45
46 public static List<Person> computeUnion(List<Person> list1, List<Person> list2) {
47 Set<Person> set1 = new HashSet<>(list1);
48 set1.addAll(list2);
49 return new ArrayList<>(set1);
50 }
51
52 public static List<Person> computeDifference(List<Person> source, List<Person> toRemove) {
53 Set<Person> set1 = new HashSet<>(source);
54 set1.removeAll(new HashSet<>(toRemove));
55 return new ArrayList<>(set1);
56 }
57}
// 自己写的计算交集
List<Person> intersection2 = list1.stream()
.filter(list2::contains)
.collect(Collectors.toList());
System.out.println("new jiaoji: " + intersection2);
// 自己写的计算差集
List<Person> fcSide = list1.stream()
.filter(item -> !list2.contains(item))
.collect(Collectors.toList());
System.out.println("new chaji: " + fcSide);
方法解释
-
计算交集 (
computeIntersection
):- 将两个列表转换为
HashSet
,利用HashSet
的特性(不允许重复元素)来去除重复项。 - 使用
retainAll
方法来保留两个集合中的共有元素。
- 将两个列表转换为
-
计算并集 (
computeUnion
):- 同样先将列表转换为
HashSet
。 - 使用
addAll
方法将另一个集合中的元素添加到当前集合中,从而实现并集操作。
- 同样先将列表转换为
-
计算差集 (
computeDifference
):- 将源列表转换为
HashSet
。 - 使用
removeAll
方法移除另一个集合中的元素,从而留下仅存在于源集合中的元素。
- 将源列表转换为
输出结果
当运行上述代码时,你会得到以下输出:
深色版本
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}]
总结
通过上述方法,我们可以轻松地计算两个List
之间的交集、并集和差集。这些操作对于数据比较和数据同步等场景非常有用。注意,在实际应用中,你需要确保你的对象具有正确的equals
和hashCode
方法实现,以保证集合操作的正确性。