public static <T, K, D, A, M extends Map<K, D>>
    FieldCollector<T, ?, M> groupingBy(
            Field<T> field,
            Function<T, K> classifier,
            Supplier<M> mapFactory,
            Collector<? super T, A, D> downstream) {

        Supplier<A> downstreamSupplier = downstream.supplier();
        BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
        BiConsumer<Map<K, A>, T> accumulator = (m, t) -> {
            K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
            A container = m.computeIfAbsent(key, k -> downstreamSupplier.get());
            downstreamAccumulator.accept(container, t);
        };
        BinaryOperator<Map<K, A>> merger = FieldCollectors.mapMerger(downstream.combiner());
        @SuppressWarnings("unchecked")
        Supplier<Map<K, A>> mangledFactory = (Supplier<Map<K, A>>) mapFactory;

        if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
            return new FieldCollectorImpl<>(field, mangledFactory, accumulator, merger, CH_ID);
        }
        else {
            @SuppressWarnings("unchecked")
            UnaryOperator<A> downstreamFinisher = (UnaryOperator<A>) downstream.finisher();
            Function<Map<K, A>, M> finisher = intermediate -> {
                intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
                @SuppressWarnings("unchecked")
                M castResult = (M) intermediate;
                return castResult;
            };
            return new FieldCollectorImpl<>(field, mangledFactory, accumulator, merger, finisher, CH_NOID);
        }
    }
A number of collectors specialized for entities. These are inspired by the
{@link java.util.stream.Collectors} class in the java standard libraries.

@author Emil Forslund
@since  3.0.2
runtime-parent/runtime-field/src/main/java/com/speedment/runtime/field/collector/FieldCollectors.java