package com.insightfullogic.java8.answers.chapter5; import java.util.*; import java.util.function.BiConsumer; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collector; public class GroupingBy<T, K> implements Collector<T, Map<K, List<T>>, Map<K, List<T>>> { private final static Set<Characteristics> characteristics = new HashSet<>(); static { characteristics.add(Characteristics.IDENTITY_FINISH); } private final Function<? super T, ? extends K> classifier; public GroupingBy(Function<? super T, ? extends K> classifier) { this.classifier = classifier; } @Override public Supplier<Map<K, List<T>>> supplier() { return HashMap::new; } @Override public BiConsumer<Map<K, List<T>>, T> accumulator() { return (map, element) -> { K key = classifier.apply(element); List<T> elements = map.computeIfAbsent(key, k -> new ArrayList<>()); elements.add(element); }; } @Override public BinaryOperator<Map<K, List<T>>> combiner() { return (left, right) -> { right.forEach((key, value) -> { left.merge(key, value, (leftValue, rightValue) -> { leftValue.addAll(rightValue); return leftValue; }); }); return left; }; } @Override public Function<Map<K, List<T>>, Map<K, List<T>>> finisher() { return map -> map; } @Override public Set<Characteristics> characteristics() { return characteristics; } }