Skip to content

Instantly share code, notes, and snippets.

@dpolivaev
Created September 25, 2019 08:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dpolivaev/50cc9eb1b75453d37195882a9fc9fb69 to your computer and use it in GitHub Desktop.
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"
@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