java8映射两个字段,Java 8:按字段对集合进行分组,并使用流将其展平并作为映射值加入集合?...

我的班有两个领域:

> MyKey – 我想分组的关键

>设置< MyEnum> – 我想要展平和合并的集合.

我有一个这样的对象列表,我想要的是获得一个Map< MyKey,Set< MyEnum>其中的值是使用此键从对象的所有myEnums连接的.

例如,如果我有三个对象:

> myKey:key1,myEnums:[E1]

> myKey:key1,myEnums:[E2]

> myKey:key2,myEnums:[E1,E3]

预期结果应该是:

key1 => [E1,E2],key2 => [E1,E3]

我想出了这段代码:

Map> map = myObjs.stream()

.collect(Collectors.groupingBy(

MyType::getMyKey,

Collectors.reducing(

new HashSet(),

MyType::getMyEnums,

(a, b) -> {

a.addAll(b);

return a;

})));

它有两个问题:

>减少内部的HashSet似乎在所有键之间共享.这就是说上面例子的实际运行结果是key1 => [E1,E2,E3],key2 => [E1,E2,E3].为什么会这样?

>即使这段代码有效,它看起来也很难看,尤其是在减少我必须手动处理构建连接集合的逻辑的部分.有没有更好的方法呢?

谢谢!

最佳答案:

请注意,您只创建一个标识对象:new HashSet< MyEnum>().

您作为第三个参数提供的BinaryOperator必须是idempotent,与常见的数学运算符相同,例如x = y z不会改变y和z的值.

这意味着您需要合并两个输入集a和b,而不更新任何一个.

此外,使用枚举,您应该使用EnumSet,而不是HashSet.

Map> map = myObjs.stream()

.collect(Collectors.groupingBy(

MyType::getMyKey,

Collectors.reducing(

EnumSet.noneOf(MyEnum.class), //

MyType::getMyEnums,

(a, b) -> {

EnumSet c = EnumSet.copyOf(a); //

c.addAll(b);

return c;

})));

UPDATE

更短,更简化的版本,在累积结果时不必继续创建新集:

Map> map = myObjs.stream()

.collect(Collectors.groupingBy(

MyType::getMyKey,

Collector.of(

() -> EnumSet.noneOf(MyEnum.class),

(r, myObj) -> r.addAll(myObj.getMyEnums()),

(r1, r2) -> { r1.addAll(r2); return r1; }

)));

标签:java,java-8,collectors

来源: https://codeday.me/bug/20190516/1115007.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值