Это немного странная ошибка.В частности, используемый вами коллектор (благодаря использованию Collectors.counting
) фактически накапливается в одноэлементные массивы примитива long
s.
public static <T> Collector<T, ?, Long> summingLong(ToLongFunction<? super T> mapper)
{
return new CollectorImpl<>(
() -> new long[1],
(a, t) -> { a[0] += mapper.applyAsLong(t); },
(a, b) -> { a[0] += b[0]; return a; },
a -> a[0], CH_NOID);
}
Когда groupingBy
делает computeIfAbsent
, он ожидает получить long[]
, но, поскольку у вас уже есть ключ для «a», вы получите Long
, который не соответствует типу, принятому аккумулятором.Это то, что выдает исключение.
A container = m.computeIfAbsent(key, k -> downstreamSupplier.get());
downstreamAccumulator.accept(container, t);
Позже они заменяют все значения карты:
intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
с использованием 'финишера', определенного выше (a -> a[0]
) перейти от long[]
с к Long
с.
Да, это немного непослушно, но вы нарушили контракт
mapFactory:поставщик, предоставляющий новую пустую карту , в которую будут вставлены результаты
, так что это также достаточно справедливо.Они берут HashMap
, который во время компиляции было решено равным Map<String, Long>
, и они вкладывают в него long[]
.Это возможно, потому что дженерики не овеществлены .Во время выполнения это просто HashMap
, способный хранить любые типы ключей и значений.