如何收集列表<;Foo>;到地图<;栏、列表<;Baz>&燃气轮机;使用Java lambdas?

如何收集列表<;Foo>;到地图<;栏、列表<;Baz>&燃气轮机;使用Java lambdas?,java,lambda,java-stream,collectors,Java,Lambda,Java Stream,Collectors,我有一个对象Foo,它引用了Bar和Baz对象: public class Foo { private Bar bar; private Baz baz; public Foo(Bar bar, Baz baz) { this.bar = bar; this.baz = baz; } } 我有一个列表,我想把它转换成地图。我希望键是条,值是列表 我可以创建一个映射,其中栏是键,值是一个列表: Map-mappartofoos=foo

我有一个对象
Foo
,它引用了
Bar
Baz
对象:

public class Foo {
    private Bar bar;
    private Baz baz;

    public Foo(Bar bar, Baz baz) {
       this.bar = bar;
       this.baz = baz;
    }
}
我有一个
列表
,我想把它转换成
地图
。我希望键是
,值是
列表

我可以创建一个
映射
,其中
是键,值是一个
列表

Map-mappartofoos=foos.stream().collect(Collectors.groupingBy(Foo::getBar));
我不知道如何执行最后一步,将值列表变成
列表
。在我没有看到的值上是否存在lambda转换?

我想您需要

list.stream().collect(groupingBy(Foo::getBar, 
    mapping(Foo::getBaz, toList())));
其中,
getBaz
是“下游收集器”,用于转换分组的
Foo
s,然后是另一个用于创建列表的收集器

我想你想要

list.stream().collect(groupingBy(Foo::getBar, 
    mapping(Foo::getBaz, toList())));

其中,
getBaz
是“下游收集器”,用于转换分组的
Foo
s,然后是另一个用于创建列表的收集器

要将经典的
分组
更改为
映射
,您需要使用允许更改映射值的方法:

  • 带有下游的版本
  • 这是一个映射操作
  • 这需要另一个操作来设置容器
//使用导入来减少收集器。冗余
//导入静态java.util.stream.Collectors.*;
Map mapBarToFoos=
collect(groupingBy(Foo::getBar,mapping(Foo::getBaz,toList());
//如果没有你,你会得到
Map mapBarToFoos=
foos.stream().collect(Collectors.groupingBy(Foo::getBar,Collectors.mapping(Foo::getBaz,Collectors.toList()));

要将经典的
分组
更改为
映射
,您需要使用允许更改映射值的方法:

  • 带有下游的版本
  • 这是一个映射操作
  • 这需要另一个操作来设置容器
//使用导入来减少收集器。冗余
//导入静态java.util.stream.Collectors.*;
Map mapBarToFoos=
collect(groupingBy(Foo::getBar,mapping(Foo::getBaz,toList());
//如果没有你,你会得到
Map mapBarToFoos=
foos.stream().collect(Collectors.groupingBy(Foo::getBar,Collectors.mapping(Foo::getBaz,Collectors.toList()));

如果您已经接近,您需要提供一个“下游”收集器来进一步完善您的标准。在这种情况下,
groupingBy
方法以及
映射
下游收集器是惯用的方法,即

list.stream().collect(groupingBy(Foo::getBar, mapping(Foo::getBaz, toList())));
这主要是通过将
映射
下游收集器应用于分类(
Foo::getBar
)函数的结果来实现的。 基本上,我们所做的是将每个
Foo
对象映射到
Baz
并将其放入一个列表中


只是想在这里展示另一个变体,尽管不如
groupingBy
方法可读:

foos.stream()
    .collect(toMap(Foo::getBar, v -> new ArrayList<>(singletonList(v.getBaz())),
            (l, r) -> {l.addAll(r); return l;}));
foos.stream()
.collect(toMap(Foo::getBar,v->newarraylist(singletonList(v.getBaz())),
(l,r)->{l.addAll(r);返回l;});
  • Foo::getBar
    是提取映射键的
    keyMapper
    函数
  • v->new ArrayList(singletonList(v))
    valueMapper
    函数提取映射值
  • (l,r)->{l.addAll(r);return l;}
    是用于 合并两个恰好具有相同
    getBar
    值的列表

如果您已经接近,您需要提供一个“下游”收集器来进一步完善您的标准。在这种情况下,
groupingBy
方法以及
映射
下游收集器是惯用的方法,即

list.stream().collect(groupingBy(Foo::getBar, mapping(Foo::getBaz, toList())));
这主要是通过将
映射
下游收集器应用于分类(
Foo::getBar
)函数的结果来实现的。 基本上,我们所做的是将每个
Foo
对象映射到
Baz
并将其放入一个列表中


只是想在这里展示另一个变体,尽管不如
groupingBy
方法可读:

foos.stream()
    .collect(toMap(Foo::getBar, v -> new ArrayList<>(singletonList(v.getBaz())),
            (l, r) -> {l.addAll(r); return l;}));
foos.stream()
.collect(toMap(Foo::getBar,v->newarraylist(singletonList(v.getBaz())),
(l,r)->{l.addAll(r);返回l;});
  • Foo::getBar
    是提取映射键的
    keyMapper
    函数
  • v->new ArrayList(singletonList(v))
    valueMapper
    函数提取映射值
  • (l,r)->{l.addAll(r);return l;}
    是用于 合并两个恰好具有相同
    getBar
    值的列表

正确的想法您只需将下游收集器传递到
映射
就可以尝试了-效果非常好。其他人的建议也同样明智,但你是第一个。非常感谢。正确的想法您只需将下游收集器传递给
映射
就可以了,最后您可以尝试一下了,它的效果非常好。其他人的建议也同样明智,但你是第一个。非常感谢。