Luk*_*fer 8 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();
Run Code Online (Sandbox Code Playgroud)
Java的:
elements.stream().filter(x -> x.getValue() == 5).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
在这两个示例中,我从列表开始,定义操作(在此示例中为过滤器)并收集结果以存储它(在此示例中的新列表中).
现在我得到了一个更复杂的案例:
data.stream()
.map( ... ).filter( ... ) // Some operations
.collect(groupingBy(Chunk::getName, summingLong(Chunk::getValue)));
Run Code Online (Sandbox Code Playgroud)
这个查询的结果是a Map<String, Long>
,我可以使用它,但是让我们说,我想继续使用这些数据而不是存储它.我目前的方法很简单:
...
.collect(groupingBy(Chunk::getName, summingLong(Chunk::getValue)))
.entrySet().stream().
.map( ... ) // Do more operations
Run Code Online (Sandbox Code Playgroud)
但是这样,我离开了流,将第一个结果存储在Map中并打开一个新流继续.有没有一种方法可以在没有收藏家的情况下进行分组,这样我就可以"留在"流中?
您可以在下游收集器中执行任何操作,只要您可以将操作描述为Collector
.目前,只有相当于中间操作map
的mapping
收集器,但Java 9也将添加filtering
和flatMapping
(您也可以在Java 8中实现)并且已经相当于几乎每个终端操作.
当然,收藏家的嵌套设备看起来完全不同于一系列Stream操作做同样的事情......
但是,如果要处理完整的组,则无法grouping
先完成收集.这不是API的限制,而是分组操作或一般任何操作的固有内容,如果要处理完整的结果,则需要首先完成操作.无论API是怎样的,例如你可以以类似collectingAndThen
的方式隐藏收集器中的后续操作,创建和填充Map
是不可避免的,因为它是维护组的映射.这些组由键和查找逻辑确定Map
,因此,例如使用SortedMap
带有自定义比较器或a IdentityHashMap
的组,可以完全改变分组逻辑.
由于 API 已经存在,你无法逃避它。
分组依据
是一个终止操作(它不返回 Stream),因此该操作将结束流。
根据您稍后想要在最后一个映射操作中执行的操作,您可以创建一个将“保留”在流中的自定义收集器;即使在内部您可能仍然会将元素收集到 Map 中。
归档时间: |
|
查看次数: |
458 次 |
最近记录: |