Предполагая, что у вас есть следующие два метода:
private boolean canConsumeList(List<?> list) {
return !list.isEmpty();
}
private <T> void consumeNonEmptyList(List<T> nonEmptyList) {
// logic here
}
вы могли бы «взломать» API Collector
следующим образом:
public final class ExtraCollectors {
public static <T, R> Collector<T, ?, ?> collectingAndConsuming(Collector<T, ?, R> downstream, Predicate<R> resultFilter, Consumer<R> resultConsumer) {
return Collectors.collectingAndThen(downstream, result -> {
if (resultFilter.test(result)) {
resultConsumer.accept(result);
}
return null;
});
}
}
, а затем использовать его следующим образом:
Stream.of("a", "b").collect(ExtraCollectors.collectingAndConsuming(
Collectors.toList(), this::canConsumeList, this::consumeNonEmptyList
));
Обратите внимание, однако, что такое решение не является чем-то, что я считаю «чистым кодом» (поэтому я назвал его «хаком»). Это может быть неинтуитивно для других разработчиков, потому что collect
сочетается с получением некоторого результата (или, другими словами, «собирая» элементы Stream
в один результат). И здесь нет результата (даже моя IDE жалуется, что «результат Stream.collect()
игнорируется»).