Skip to content

Instantly share code, notes, and snippets.

@overpas
Last active October 14, 2020 12:39
Show Gist options
  • Save overpas/ccc39b75f17a1c65682c071045c1a079 to your computer and use it in GitHub Desktop.
Save overpas/ccc39b75f17a1c65682c071045c1a079 to your computer and use it in GitHub Desktop.
Java Streams API Elements Collectors
public final class ElementCollectors {
private static final String MESSAGE_SINGLE_MANY_ITEMS = "More than one items";
private ElementCollectors() {
// utils
}
public static <T> Collector<T, ?, T> single(String errorMessage) {
return single(Collectors.toList(), errorMessage);
}
public static <T> Collector<T, ?, T> single(Predicate<T> predicate) {
return single(predicate, MESSAGE_SINGLE_MANY_ITEMS);
}
public static <T> Collector<T, ?, T> single(Predicate<T> predicate, String errorMessage) {
return single(filteringCollector(predicate), errorMessage);
}
public static <T> Collector<T, ?, T> single(Collector<T, ?, List<T>> collector,
String errorMessage) {
return one(
collector,
list -> {
if (list.isEmpty()) {
throw new NoSuchElementException();
}
if (list.size() != 1) {
throw new IllegalStateException(errorMessage);
}
return list.get(0);
}
);
}
public static <T> Collector<T, ?, Optional<T>> optional(Predicate<T> predicate) {
return optional(filteringCollector(predicate));
}
public static <T> Collector<T, ?, Optional<T>> optional(Collector<T, ?, List<T>> collector) {
return one(collector, list -> list.size() == 1 ? Optional.of(list.get(0)) : Optional.empty());
}
public static <T> Collector<T, ?, T> first(Predicate<T> predicate) {
return first(filteringCollector(predicate));
}
public static <T> Collector<T, ?, T> first(Collector<T, ?, List<T>> collector) {
return one(
collector,
list -> {
if (list.isEmpty()) {
throw new NoSuchElementException();
}
return list.get(0);
}
);
}
public static <T, R> Collector<T, ?, R> one(Collector<T, ?, List<T>> collector,
Function<List<T>, R> finalizer) {
return Collectors.collectingAndThen(collector, finalizer);
}
private static <T> Collector<T, List<T>, List<T>> filteringCollector(Predicate<T> predicate) {
return Collector.of(
(Supplier<List<T>>) ArrayList::new,
(list, t) -> {
if (predicate.test(t)) {
list.add(t);
}
},
(left, right) -> {
left.addAll(right);
return left;
}
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment