【问题标题】:Grouping Objects from Different classes using java 8 streams使用 java 8 流对来自不同类的对象进行分组
【发布时间】:2021-11-14 06:32:23
【问题描述】:

我有以下课程

class Pojo1 {
    pojo2 item;
}

class pojo2 {
    pojo3 item;
}

class pojo3 {
   pojo4 item;
}

我想从 pojo1 流中将它们累积如下。 (流多个)

Map<pojo4,Map<pojo3,List<pojo2>>>  k=new HashMap()<>;

谁能帮我在流中做到这一点?我还想根据以下属性对地图进行排序:

   (pojo4 - some property)
   (pojo3 - some property)
   (pojo2- some property)

我想同时使用 java 8 流和并行流。

【问题讨论】:

    标签: java java-stream


    【解决方案1】:

    首先,提到的 POJO 类 Pojo4Pojo3 需要实现 hashCodeequals 才能用作映射键以及属性的相关 getter。

    转换应该使用常见的Collectors.groupingBy / Collectors.mapping 收集器,并且需要初始重新映射到包含两个对象的普通容器,例如Pair

    以下示例使用 Java 11 Map.entry 作为中间容器。

    static Map<Pojo4, <Map<Pojo3, List<Pojo2>>>> convert(Stream<Pojo1> ones) {
        return ones              // Stream<Pojo1>
            .map(Pojo1::getItem) // Stream<Pojo2>
            .map(p2 -> Map.entry(p2, p2.getItem())) // Stream<Map.Entry<Pojo2, Pojo3>>
            .collect(Collectors.groupingBy(
                me -> me.getValue().getItem(), // key: Pojo4
                Collectors.groupingBy(
                    me -> me.getValue(), // key: Pojo3
                    Collectors.mapping(
                        Map.Entry::getKey, Collectors.toList()
                    )
                )
            ));
    }
    

    同样,排序版本可以使用Collectors.groupingBy 和地图供应商来实现;另外List&lt;Pojo2&gt; 应该使用collectingAndThen 进行排序。

    假设Pojo2Pojo3Pojo4 有getter getField 对属性进行排序,则提供以下更新:

    static Map<Pojo4, <Map<Pojo3, List<Pojo2>>>> convert(Stream<Pojo1> ones) {
        return ones
            .map(Pojo1::getItem) // Stream<Pojo2>
            .map(p2 -> Map.entry(p2, p2.getItem())) // Stream<Map.Entry<Pojo2, Pojo3>>
            .collect(Collectors.groupingBy(
                me -> me.getValue().getItem(), // key: Pojo4
                () -> new TreeMap(Comparator.comparing(Pojo4::getField)),
                Collectors.groupingBy(
                    me -> me.getValue(), // key: Pojo3
                    () -> new TreeMap(Comparator.comparing(Pojo3::getField)),
                    Collectors.mapping(
                        Map.Entry::getKey, Collectors.collectingAndThen(
                            Collectors.toList(), // List<Pojo2>
                            list -> {
                                list.sort(Comparator.comparing(Pojo2::getField)); 
                                return list;
                            }
                        )
                    )
                )
            ));
    }
    

    免责声明:上面的代码示例尚未经过测试,因此可能需要进行额外的调整。

    【讨论】:

    • 谢谢,但是它不起作用,它可以更容易理解吗:( 类型不匹配:无法从 Map>> 转换为 Map>>
    • 什么不起作用? pojo 类中有很多东西要定义。
    • 能不能再简单点恐怕不行。
    • new TreeMap(Comparator.comparing(Pojo3::getField)),new TreeMap(Comparator.comparing(Pojo4::getField)) 两个树形图的类型参数可能是什么?如 信息?
    • 请问groupBy和映射操作的结果是什么?
    猜你喜欢
    • 2020-05-20
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多