CountingCollector.java (1772B)
1 package osm.protobuf.common; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.Map; 6 import java.util.Stack; 7 import java.util.Map.Entry; 8 import java.util.Set; 9 import java.util.concurrent.atomic.AtomicInteger; 10 import java.util.function.BiConsumer; 11 import java.util.function.BinaryOperator; 12 import java.util.function.Function; 13 import java.util.function.Supplier; 14 import java.util.stream.Collector; 15 16 public 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 }