Java 8 GroupingBy 进入 Peek

标签 java java-8 java-stream

我最近了解了 Java 8 中的流并开始使用它们。现在我有一个关于 groupingBy 的问题采集方法:

我通常使用 .NET,所以我比较了(知道它们相同)Java Stream<T>使用 .NET IEnumerable<T> .在这个比较之后,List<T>存储元素和特定的 Stream/IEnumerable应用操作。一个例子:

C#:

elements.Where(x => x.Value == 5).ToList();

Java:

elements.stream().filter(x -> x.getValue() == 5).collect(Collectors.toList());

在这两个示例中,我都从一个列表开始,定义操作(在本示例中为过滤器)并收集结果以将其存储(在本示例中为新列表)。

现在我有一个更复杂的案例:

data.stream()
    .map( ... ).filter( ... ) // Some operations
    .collect(groupingBy(Chunk::getName, summingLong(Chunk::getValue)));

此查询的结果是 Map<String, Long>我可以处理这个,但可以说,我想继续处理这些数据而不是存储它。我目前的方法很简单:

    ...
    .collect(groupingBy(Chunk::getName, summingLong(Chunk::getValue)))
    .entrySet().stream().
    .map( ... ) // Do more operations

但是通过这种方式,我离开流,将第一个结果存储在 Map 中并打开一个新流以继续。有没有办法在没有收集器的情况下进行分组,以便我可以“留在”流中?

最佳答案

您可以在下游收集器中做任何您想做的事情,只要您可以将操作描述为Collector。目前,只有一个相当于中间操作的map,即mapping。收集器,但 Java 9 还将添加 filteringflatMapping (您也可以在 Java 8 中自己实现)并且几乎每个终端操作都已经有了等效项。

当然,一个嵌套的收集器装置看起来与做同样事情的一系列 Stream 操作完全不同......

但是,如果您想处理完整的组,则无法绕过先完成 grouping 集合。这不是 API 的限制,而是分组操作或任何一般操作所固有的,如果你想处理一个完整的结果,你需要先完成操作。无论 API 看起来如何,例如您可以将收集器中的后续操作隐藏在 collectingAndThen 中-like 方式,创建和填充 Map 是不可避免的,因为它是维护组的 map 。这些组由 Map 的键和查找逻辑确定,因此,例如使用带有自定义比较器的 SortedMapIdentityHashMap,可以完全改变分组逻辑。

关于Java 8 GroupingBy 进入 Peek,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41549005/

相关文章:

java - 无法将 ISO 8601 格式的字符串解析为 Java 8 日期,在偏移量中缺少冒号

java - 如何检查 Java 8 Stream 是否为空?

Java 使用 Stream 初始化对象并设置属性

java - 如何在 Java 8 的 map 中展平列表

与流映射的 Java 8 列表

java - 是否有基于 Java 的光线追踪模型可以适用于水下声学?

java - PDFbox库页面迭代

Java 8 不兼容类型错误

Java-创建子类对象后父类(super class)对象去了哪里

java - 在 SharedPreference.Editor 上调用 putString 时,我的应用程序强制关闭