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)

也就是说,尚不清楚您实际上要使用过滤函数做什么,该函数需要三个参数而不是两个参数。

我怀疑您正在尝试将函数映射到与过滤器匹配的元素上,但这本身就是一个映射,您可以很容易地做到这一点:

 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 回答
6

在 Java 9 中有一个新的过滤收集器:

Map<Department, Set<Employee>> wellPaidEmployeesByDepartment = employees.stream()
  .collect(groupingBy(Employee::getDepartment,
      filtering(e -> e.getSalary() > 2000, toSet())));
于 2017-12-15T22:33:52.273 回答