使用Stream流完成并集、交集和差集

一、介绍

本文将进行介绍使用Stream流的方式,来完成对象集合的并集交集差集

二、代码

先建立一个User.java,一会使用它来创建集合,并重写了它的equals方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.banmoon.test;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.Objects;

/**
* @author banmoon
*/
@Data
@AllArgsConstructor
public class User {

private Integer id;

private String name;

@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof User))
return false;
User user = (User) o;
return Objects.equals(getId(), user.getId()) && Objects.equals(getName(), user.getName());
}

@Override
public int hashCode() {
return Objects.hash(getId(), getName());
}

}

1)并集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.banmoon.test;

import cn.hutool.core.collection.CollUtil;
import org.junit.Test;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Stream测试
*
* @author banmoon
*/
public class StreamTest {

public static final List<User> userList1 = CollUtil.newArrayList(
new User(1, "banmoon1"),
new User(2, "banmoon2"),
new User(3, "banmoon3")
);

public static final List<User> userList2 = CollUtil.newArrayList(
new User(2, "banmoon2"),
new User(3, "banmoon3"),
new User(4, "banmoon4")
);

/**
* 并集
*/
@Test
public void concat() {
List<User> newList = Stream.concat(userList1.stream(), userList2.stream())
.distinct()
.collect(Collectors.toList());
System.out.println(newList);
}

}

测试

image-20230109184230219

2)交集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.banmoon.test;

import cn.hutool.core.collection.CollUtil;
import org.junit.Test;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Stream测试
*
* @author banmoon
*/
public class StreamTest {

public static final List<User> userList1 = CollUtil.newArrayList(
new User(1, "banmoon1"),
new User(2, "banmoon2"),
new User(3, "banmoon3")
);

public static final List<User> userList2 = CollUtil.newArrayList(
new User(2, "banmoon2"),
new User(3, "banmoon3"),
new User(4, "banmoon4")
);

/**
* 交集
*/
@Test
public void union() {
List<User> newList = userList1.stream()
.filter(user1 -> {
return userList2.stream().anyMatch(user1::equals);
}).collect(Collectors.toList());
System.out.println(newList);
}

}

测试

image-20230109184302111

3)差集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.banmoon.test;

import cn.hutool.core.collection.CollUtil;
import org.junit.Test;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Stream测试
*
* @author banmoon
*/
public class StreamTest {

public static final List<User> userList1 = CollUtil.newArrayList(
new User(1, "banmoon1"),
new User(2, "banmoon2"),
new User(3, "banmoon3")
);

public static final List<User> userList2 = CollUtil.newArrayList(
new User(2, "banmoon2"),
new User(3, "banmoon3"),
new User(4, "banmoon4")
);

/**
* 差集
*/
@Test
public void difference() {
List<User> newList = userList1.stream()
.filter(user1 -> {
return userList2.stream().noneMatch(user1::equals);
}).collect(Collectors.toList());
System.out.println(newList);
}

}

测试

image-20230109184317199


上述的图示

image-20230109185719509

三、抽取公共方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.banmoon.test.utils;

import java.util.List;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Stream流工具类
*
* @author banmoon
*/
public class StreamUtil {

/**
* 并集
*
* @param list1 第一个对象list
* @param list2 第二个对象list
* @param function 转换
* @param <T> 对象
* @param <R> 转换后的对象
* @return 结果对象集合
*/
public static <T, R> List<R> concat(List<T> list1, List<T> list2, Function<T, R> function) {
return Stream.concat(list1.stream(), list2.stream())
.map(function)
.collect(Collectors.toList());
}

/**
* 获取两个list的交集
*
* @param list1 第一个对象list
* @param list2 第二个对象list
* @param predicate 判断两个list是否相等
* @param function 转换输出的结果
* @param <T1> 第一个对象
* @param <T2> 第二个对象
* @param <R> 结果对象
* @return 结果对象集合
*/
public static <T1, T2, R> List<R> union(List<T1> list1, List<T2> list2, BiPredicate<T1, T2> predicate, Function<T1, R> function) {
return list1.stream()
.filter(a -> list2.stream().anyMatch(b -> predicate.test(a, b)))
.map(function)
.collect(Collectors.toList());
}

/**
* 获取两个list的差集,简单的来说就是 list1 - list2 = list3
*
* @param list1 第一个对象list
* @param list2 第二个对象list
* @param predicate 判断两个list是否相等,相等的才会减去
* @param function 转换输出的结果
* @param <T1> 第一个对象
* @param <T2> 第二个对象
* @param <R> 结果对象
* @return 结果对象集合
*/
public static <T1, T2, R> List<R> difference(List<T1> list1, List<T2> list2, BiPredicate<T1, T2> predicate, Function<T1, R> function) {
return list1.stream()
.filter(a -> list2.stream().noneMatch(b -> predicate.test(a, b)))
.map(function)
.collect(Collectors.toList());
}

}

四、最后

我是半月,你我一同共勉!!!