Lambda 如何根据发生次数筛选条目?

Lambda 如何根据发生次数筛选条目?,lambda,java-8,java-stream,Lambda,Java 8,Java Stream,使用流API,在使用groupingBy->counting操作收集包含基于出现次数过滤器的条目后,如何进行过滤 鉴于以下情况: Map<Integer, Long> counts = Stream.of(1, 2, 2, 3, 4, 5, 5) .collect(groupingBy(n -> n, counting())); 对于依赖于已经看到的值的操作,没有办法构建映射或类似的数据结构。例如,distinct,它看起来像是操作链中的一个步骤,但如果不在内

使用流API,在使用
groupingBy
->
counting
操作收集包含基于出现次数过滤器的条目后,如何进行过滤

鉴于以下情况:

Map<Integer, Long> counts = Stream.of(1, 2, 2, 3, 4, 5, 5)
        .collect(groupingBy(n -> n, counting()));

对于依赖于已经看到的值的操作,没有办法构建映射或类似的数据结构。例如,
distinct
,它看起来像是操作链中的一个步骤,但如果不在内部构建映射(或类似映射的结构),则无法工作

您可以使用

Map<Integer, Long> counts = Stream.of(1, 2, 2, 3, 4, 5, 5)
    .collect(collectingAndThen(groupingBy(n -> n, counting()),
       map -> map.entrySet().stream()
         .filter(n -> n.getValue() > 1)
         .collect(toMap(Entry::getKey, Entry::getValue))
    ));

它允许在遇到一种类型的第二项时,立即将后续操作应用到终端操作,而无需处理所有项或等待流的结束,并与
并行执行和/或短路操作相协调,如
限制
findAny
,等等。

鉴于distinct并行工作,我确信可以提供一个拆分器,用于保存接受满足某个函数的第一个事件的次数(对于大于的示例)。拆分器需要参数来控制在接受计数之前是否必须访问相同的所有对象。如果对流进行排序,则每个接受都会在流管道中更快地传递对象。这远远超出了您所写问题的范围。您的流没有sorted属性,您的问题中所示的操作将不会从这种复杂的实现中受益,因为您正在将结果收集到一个从出现次数到出现次数的映射中,这无论如何都需要处理每个项。简单的示例,也许我不应该收集到映射,我用它来强调我试图实现的目标,最终的结果是什么并不重要,拆分器不需要对上游进行排序,只是强调它可能会受益。似乎没有可用的东西,我可能会尝试使用拆分器实现来处理我所描述的。也许我的更新更接近您最初想要实现的。好了,这就是我想要的:)我还尝试编写一个流实现,它可以使用谓词来允许对计数进行运算,但是流API中所有有用的类都是私有的,这使得它更具挑战性。谢谢你,霍尔格。
Map<Integer, Long> counts = Stream.of(1, 2, 2, 3, 4, 5, 5)
    .collect(collectingAndThen(groupingBy(n -> n, counting()),
       map -> map.entrySet().stream()
         .filter(n -> n.getValue() > 1)
         .collect(toMap(Entry::getKey, Entry::getValue))
    ));
Map<Integer, Long> counts = Stream.of(1, 2, 2, 3, 4, 5, 5)
    .collect(groupingBy(n -> n, HashMap::new, counting()));
counts.values().removeIf(count -> count < 2);
ConcurrentHashMap<Integer,Integer> counts=new ConcurrentHashMap<>();
Stream.of(1, 2, 2, 3, 4, 5, 5)
      .filter(i -> counts.merge(i, 1, Integer::sum)==2)
      .forEach(System.out::println);