Потоки Java с генериками - PullRequest
       1

Потоки Java с генериками

5 голосов
/ 01 апреля 2019

У меня есть общая функция, которая принимает Collection<? extends T> ts.

Я тоже прохожу:

Function<? extends T, ? extends K> classifier, который сопоставляет каждый элемент T с ключом K (возможно наличие дубликатов)

Function<? extends T, Integer> evaluator, который дает целое значение для элемента.

Сама функция имеет встроенный расчет ("int to int") для каждого произведенного Integer (может быть что-то вроде возведения в квадрат для нашего примера)

Наконец, я хотел бы суммировать все значения для каждого ключа.

Итак, конечный результат: Map<K, Integer>.

Например,
Допустим, у нас есть список ["a","a", "bb"], и мы используем Function.identity для классификации, String::length для оценки и возведения в квадрат как встроенную функцию. Тогда возвращаемая карта будет: {"a": 2, "b": 4}

Как я могу это сделать? (Я думаю, что желательно, используя Collectors.groupingBy)

Ответы [ 2 ]

4 голосов
/ 01 апреля 2019

Вот один из способов сделать это:

public static <T,K> Map<K,Integer> mapper (
    Collection<T> ts,
    Function<T, K> classifier,
    Function<T, Integer> evaluator,
    Function<Integer,Integer> calculator) 
{
     return
        ts.stream()
          .collect(Collectors.groupingBy(classifier,
                                         Collectors.summingInt(t->evaluator.andThen(calculator).apply(t))));
}

Выход для:

System.out.println (mapper(Arrays.asList("a","a","bb"),Function.identity(),String::length,i->i*i));

есть

{bb=4, a=2}
2 голосов
/ 01 апреля 2019

Или другой подход:

private static <K, T> Map<K, Integer> map(Collection<? extends T> ts,
                                          Function<? super T, ? extends K> classifier,
                                          Function<? super T, Integer> evaluator,
                                          Function<Integer, Integer> andThen) {

    return ts.stream()
             .collect(Collectors.groupingBy(
                 classifier,
                 Collectors.mapping(evaluator.andThen(andThen),
                                    Collectors.reducing(0, Integer::sum))
             ));

}

И используйте его с:

public static void main(String[] args) {

    System.out.println(map(
        Arrays.asList("a", "a", "bb"),
        Function.identity(),
        String::length,
        x -> x * x));

}
...