Skip to content

Instantly share code, notes, and snippets.

@dhinojosa
Last active March 10, 2024 22:26
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 dhinojosa/7e3ba5de67270f15191c4b972710b662 to your computer and use it in GitHub Desktop.
Save dhinojosa/7e3ba5de67270f15191c4b972710b662 to your computer and use it in GitHub Desktop.
GroupBy as a Gatherer
static class GroupBy<T, K> implements Gatherer<T, HashMap<K, List<T>>, Map.Entry<K, List<T>>> {
private final Function<T, K> groupFunction;
public GroupBy(Function<T, K> groupFunction) {
this.groupFunction = groupFunction;
}
@Override
public Supplier<HashMap<K, List<T>>> initializer() {
return HashMap::new;
}
@Override
public Integrator<HashMap<K, List<T>>, T, Map.Entry<K, List<T>>> integrator() {
return (state, element, _) -> {
K result = groupFunction.apply(element);
state.computeIfAbsent(result, _ -> new ArrayList<>());
state.get(result).add(element);
return true;
};
}
public static <T, K> Gatherer<T, HashMap<K, List<T>>, Map.Entry<K, List<T>>> groupBy(Function<T, K> groupFunction) {
return new GroupBy<>(groupFunction);
}
@Override
public BiConsumer<HashMap<K, List<T>>, Downstream<? super Map.Entry<K, List<T>>>> finisher() {
return (kListHashMap, downstream) -> kListHashMap.entrySet().forEach(downstream::push);
}
}
@Test
void testGroupByAsGatherer() {
System.out.println(IntStream.range(0, 100).boxed()
.gather(groupBy(i -> i % 2 == 0 ? "even" : "odd"))
.collect(Collectors.toList()));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment