加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 是否可以在收集器分组的情况下对每个List进行操作而不创

发布时间:2020-12-15 04:47:26 所属栏目:Java 来源:网络整理
导读:我有以下代码在List上执行分组,然后对每个分组列表进行操作,然后将其转换为单个项目: MapInteger,ListRecord recordsGroupedById = myList.stream() .collect(Collectors.groupingBy(r - r.get("complex_id")));ListComplex whatIwant = recordsGroupedById
我有以下代码在List上执行分组,然后对每个分组列表进行操作,然后将其转换为单个项目:

Map<Integer,List<Record>> recordsGroupedById = myList.stream()
    .collect(Collectors.groupingBy(r -> r.get("complex_id")));

List<Complex> whatIwant = recordsGroupedById.values().stream().map(this::toComplex)
    .collect(Collectors.toList());

toComplex函数如下所示:

Complex toComplex(List<Record> records);

我觉得我可以在不创建中间地图的情况下做到这一点,也许使用reduce.有任何想法吗?

输入流按照我想在流中顺序分组的元素进行排序.在正常的循环结构中,我能够确定下一组何时开始并在那时创建“复杂”.

解决方法

那么你可以避免使用Map(老实说!)并使用我的 StreamEx库在单一管道中执行所有操作:

List<Complex> result = StreamEx.of(myList)
        .sortedBy(r -> r.get("complex_id"))
        .groupRuns((r1,r2) -> r1.get("complex_id").equals(r2.get("complex_id")))
        .map(this::toComplex)
        .toList();

这里我们首先按complex_id对输入进行排序,然后使用groupRuns自定义中间操作,如果应用于两个相邻元素的给定BiPredicate返回true,则将相邻的stream元素组合到List.然后,您有一个列表流,这些列表映射到Complex对象流,最后收集到列表中.

实际上没有中间映射,groupRuns实际上是懒惰的(在顺序模式下,它一次只保留一个中间列表),它也很好地并行化.另一方面,我的测试表明,对于未排序的输入,这种解决方案比基于groupingBy的解决方案要慢,因为它涉及对整个输入进行排序.当然sortedBy(这只是排序的快捷方式(Comparator.comparing(…)))需要中间内存来存储输入.如果您的输入已经排序(或至少部分排序,因此TimSort可以快速执行),那么此类解决方案通常比groupingBy更快.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读