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
| @SafeVarargs @SuppressWarnings("unchecked") public static <T, K, D, A, M extends Map<K, D>> M listGroupBy(List<T> list, Function<T, K> sFunction, Collector<? super T, A, D> downstream, boolean isParallel, Consumer<T>... peeks) { boolean hasFinished = downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH); return peekStream(list, isParallel, peeks).collect(new Collector<T, HashMap<K, A>, M>() { @Override public Supplier<HashMap<K, A>> supplier() { return HashMap::new; }
@Override public BiConsumer<HashMap<K, A>, T> accumulator() { return (m, t) -> { K key = Optional.ofNullable(t).map(sFunction).orElse(null); A container = m.computeIfAbsent(key, k -> downstream.supplier().get()); downstream.accumulator().accept(container, t); }; }
@Override public BinaryOperator<HashMap<K, A>> combiner() { return (m1, m2) -> { for (Map.Entry<K, A> e : m2.entrySet()) { m1.merge(e.getKey(), e.getValue(), downstream.combiner()); } return m1; }; }
@Override public Function<HashMap<K, A>, M> finisher() { return hasFinished ? i -> (M) i : intermediate -> { intermediate.replaceAll((k, v) -> (A) downstream.finisher().apply(v)); @SuppressWarnings("unchecked") M castResult = (M) intermediate; return castResult; }; }
@Override public Set<Characteristics> characteristics() { return hasFinished ? Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH)) : Collections.emptySet(); } }); }
|