I have a generic function which accepts Collection<? extends T> ts
.
I'm also passing:
Function<? extends T, ? extends K> classifier
which maps each item T
to a key K
(possible to have duplicates)
Function<? extends T, Integer> evaluator
which gives an integer value for the item.
The function itself has a built-in calculation ("int to int
") for every produced Integer
(could be something like squaring for our example)
Finally, I'd like to sum all of the values for each key.
So the end result is: Map<K, Integer>
.
For example,
Let's say we have the list ["a","a", "bb"]
and we use Function.identity
to classify, String::length
to evaluate and squaring as the built-in function. Then the returned map will be: {"a": 2, "b": 4}
How can I do that? (I guess that preferably using Collectors.groupingBy
)
Here's one way to do it:
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))));
}
The output for:
System.out.println (mapper(Arrays.asList("a","a","bb"),Function.identity(),String::length,i->i*i));
is
{bb=4, a=2}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With