私が知っている唯一の他の方法は、事前にフィルタリングを行うことです。つまり、
stream.filter(filterPredicate).collect(collector)
とはいえ、2 つではなく 3 つの引数を取るフィルター関数で実際に何をしようとしているのかは明確ではありません。
フィルターに一致する要素に関数をマップしようとしていると思われますが、それ自体がマップであり、簡単に実行できます。
Collectors.mapping(input -> condition(input) ? function(input) : input, collector)
独自のコレクターを作成することは、実際にはそれほど難しくありません。
static <T, A, R> Collector<T, A, R> filtering(
Predicate<? super T> filter, Collector<T, A, R> collector) {
return Collector.of(
collector.supplier(),
(accumulator, input) -> {
if (filter.test(input)) {
collector.accumulator().accept(accumulator, input);
}
},
collector.combiner(),
collector.finisher());
}