6

コレクションをグループ化したいのですが、集計にいくつかの値を含めたくありません。それを行うための最良の解決策は何ですか?

ソリューションはコレクターになる可能性がありますfiltering(Predicate,Collector)が、そのようなコレクターはありません。独自のコレクターを実装せずにそれを行う方法はありますか?

IntStream.range(0,100).collect(
    groupingBy(
       i -> i % 3,
       HashMap::new,
       filtering( i -> i % 2 == 0, toSet() )
    )
);
4

2 に答える 2

13

私が知っている唯一の他の方法は、事前にフィルタリングを行うことです。つまり、

 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());
}
于 2015-10-07T20:31:14.533 に答える