java多层嵌套填空_Java 8嵌套(多级)组

我有几个类,如下

class Pojo {

List items;

}

class Item {

T key1;

List subItems;

}

class SubItem {

V key2;

Object otherAttribute1;

}

我想基于key1聚合项目,对于每个聚合,子项应由key2按以下方式聚合:

Map>

Java 8 Collectors.groupingBy嵌套是如何实现的?

我正在尝试一些东西并且中途停留

pojo.getItems()

.stream()

.collect(

Collectors.groupingBy(Item::getKey1, /* How to group by here SubItem::getKey2*/)

);

注意:这与级联分组不同,后者根据here中讨论的同一对象中的字段进行多级聚合

解决方法:

您不能通过多个键对单个项目进行分组,除非您接受该项目可能出现在多个组中.在这种情况下,您想要执行一种flatMap操作.

实现此目的的一种方法是使用Stream.flatMap和一个临时对,在收集之前保存Item和SubItem的组合.由于缺少标准对类型,典型的解决方案是使用Map.Entry:

Map>> result = pojo.getItems().stream()

.flatMap(item -> item.subItems.stream()

.map(sub -> new AbstractMap.SimpleImmutableEntry<>(item, sub)))

.collect(Collectors.groupingBy(e -> e.getKey().getKey1(),

Collectors.mapping(Map.Entry::getValue,

Collectors.groupingBy(SubItem::getKey2))));

不需要这些临时对象的替代方法是在收集器中执行flatMap操作,但遗憾的是,直到Java 9,flatMapping才会出现.

有了它,解决方案看起来像

Map>> result = pojo.getItems().stream()

.collect(Collectors.groupingBy(Item::getKey1,

Collectors.flatMapping(item -> item.getSubItems().stream(),

Collectors.groupingBy(SubItem::getKey2))));

如果我们不想等待Java 9,我们可能会在代码库中添加一个类似的收集器,因为它实现起来并不难:

static Collector flatMapping(

Function super T,? extends Stream extends U>> mapper,

Collector super U,A,R> downstream) {

BiConsumer acc = downstream.accumulator();

return Collector.of(downstream.supplier(),

(a, t) -> { try(Stream extends U> s=mapper.apply(t)) {

if(s!=null) s.forEachOrdered(u -> acc.accept(a, u));

}},

downstream.combiner(), downstream.finisher(),

downstream.characteristics().toArray(new Collector.Characteristics[0]));

}

标签:java,java-8,java-stream,lambda,collections

来源: https://codeday.me/bug/20190916/1807042.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值