Created
September 25, 2019 08:34
-
-
Save dpolivaev/50cc9eb1b75453d37195882a9fc9fb69 to your computer and use it in GitHub Desktop.
A method creating a single collector given a list of collectors, see https://stackoverflow.com/a/32072206/1833472 "groupingBy with multiple Collectors"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@SuppressWarnings({"null", "unchecked"}) | |
public static <V, R> Collector<V, ?, List<R>> combine(List<Collector<V, ?, R>> collectors) { | |
final Supplier<List<Object>> supplier = () -> collectors.stream().map(Collector::supplier) | |
.map(Supplier::get).collect(Collectors.toList()); | |
final BiConsumer<List<Object>, V> biConsumer = (List<Object> list, V e) -> IntStream.range(0, collectors.size())// | |
.forEach(i -> ((BiConsumer<Object, V>) collectors.get(i).accumulator()).accept(list.get(i), e)); | |
final BinaryOperator<List<Object>> binaryOperator = (List<Object> l1, List<Object> l2) -> { | |
IntStream.range(0, collectors.size()).forEach( | |
i -> l1.set(i, ((BinaryOperator<Object>) collectors.get(i).combiner()).apply(l1.get(i), l2.get(i)))); | |
return l1; | |
}; | |
Function<List<Object>, List<R>> function = (List<Object> list) -> | |
IntStream.range(0, collectors.size()).mapToObj( | |
i ->((Function<Object, R>) collectors.get(i).finisher()).apply(list.get(i))).collect(Collectors.toList()); | |
return Collector.of( supplier, biConsumer, binaryOperator, function); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment