CountingCollector.java (1772B) download
1package osm.protobuf.common;
2
3import java.util.ArrayList;
4import java.util.List;
5import java.util.Map;
6import java.util.Stack;
7import java.util.Map.Entry;
8import java.util.Set;
9import java.util.concurrent.atomic.AtomicInteger;
10import java.util.function.BiConsumer;
11import java.util.function.BinaryOperator;
12import java.util.function.Function;
13import java.util.function.Supplier;
14import java.util.stream.Collector;
15
16public class CountingCollector
17 implements Collector<Class<?>, Stack<Entry<Class<?>, AtomicInteger>>, List<Entry<Class<?>, Integer>>> {
18 @Override
19 public Supplier<Stack<Entry<Class<?>, AtomicInteger>>> supplier() {
20 return Stack::new;
21 }
22
23 @Override
24 public BiConsumer<Stack<Entry<Class<?>, AtomicInteger>>, Class<?>> accumulator() {
25 return (stack, element) -> {
26 if (stack.isEmpty() || !stack.peek().getKey().equals(element)) {
27 stack.add(Map.entry(element, new AtomicInteger(1)));
28 } else {
29 stack.peek().getValue().incrementAndGet();
30 }
31 };
32 }
33
34 @Override
35 public BinaryOperator<Stack<Entry<Class<?>, AtomicInteger>>> combiner() {
36 return (left, right) -> {
37 left.addAll(right);
38 return left;
39 };
40 }
41
42 @Override
43 public Function<Stack<Entry<Class<?>, AtomicInteger>>, List<Entry<Class<?>, Integer>>> finisher() {
44 return stack -> {
45 List<Entry<Class<?>, Integer>> list = new ArrayList<>();
46
47 for (Entry<Class<?>, AtomicInteger> entry : stack)
48 list.add(Map.entry(entry.getKey(), entry.getValue().get()));
49
50 return list;
51 };
52 }
53
54 @Override
55 public Set<Characteristics> characteristics() {
56 return Set.of();
57 }
58}