自定义 Collector

自定义 Collector

如何手写 stream 流中的 Collector

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

import com.sun.org.apache.regexp.internal.RE;
import org.yyh.reptile.entity.Msg;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collector;

public class TestExample {
public static void main(String[] args) {
List<Msg> msgList = Arrays.asList(
new Msg("1", 1L),
new Msg("2", 3L),
new Msg("3", 3L),
new Msg("4", 4L),
new Msg("5", 4L)
);
// 手写 Collectors.toList()
ArrayList<Object> collect = msgList.stream()
.collect(Collector.of(
// 数据容器
ArrayList::new,
// 累加器,操作元素和数据容器
ArrayList::add,
// 并行流收集器,并行流合并方法
(left, right) -> {
left.addAll(right);
return left;
},
Collector.Characteristics.IDENTITY_FINISH
));
collect.forEach(System.out::println);
// 手写 分组
HashMap<Long, List<Msg>> hashMap = msgList.stream()
.collect(Collector.of(
HashMap::new,
(map, msg) -> {
// 不存在 new 后返回,存在直接返回
map.computeIfAbsent(msg.getCreateTime(), k -> new ArrayList<>()).add(msg);
},
(left, right) -> {
right.forEach((k, v) -> left.merge(k, v, (list, newList) -> {
list.addAll(newList);
return list;
}));
return left;
},
Collector.Characteristics.IDENTITY_FINISH,
// 跳过合并操作,直接放在一个线程安全的集合中
// 如果未指定该 UNORDERED,则会创建多个线程安全集合,再合并到一起,主要是保证有序数据源的有序性
Collector.Characteristics.CONCURRENT,
// 只会创建一个线程安全集合,所有元素都只对这个集合操作
Collector.Characteristics.UNORDERED
));
// 并行流
msgList.parallelStream()
// 并行有序
.forEachOrdered(System.out::println);
}
}