我的一位同事向我提出了一个有趣的问题,我无法找到一个整洁而漂亮的Java 8解决方案.问题是流过POJO列表,然后根据多个属性在地图中收集它们 - 映射导致POJO多次出现
想象一下以下POJO:
private static class Customer {
public String first;
public String last;
public Customer(String first, String last) {
this.first = first;
this.last = last;
}
public String toString() {
return "Customer(" + first + " " + last + ")";
}
}
Run Code Online (Sandbox Code Playgroud)
将其设置为List<Customer>:
// The list of customers
List<Customer> customers = Arrays.asList(
new Customer("Johnny", "Puma"),
new Customer("Super", "Mac"));
Run Code Online (Sandbox Code Playgroud)
备选方案1:使用Map"流"外部(或更确切地说是外部forEach).
// Alt 1: not pretty since the resulting map is …Run Code Online (Sandbox Code Playgroud) 我想学习如何使用Java 8语法与流,并有点卡住.
当你为每个值都有一个键时,很容易分组.但是如果我为每个值都有一个键列表并且仍然想用groupingBy对它们进行分类呢?我是否必须将其分解为多个语句,或者可能有一些流魔术可以使其更简单.
这是基本代码:
List<Album> albums = new ArrayList<>();
Map<Artist, List<Album>> map = albums.stream().collect(Collectors.groupingBy(this::getArtist));
Run Code Online (Sandbox Code Playgroud)
如果每个专辑只有一个艺术家,那么效果很好.但我必须返回一个列表,因为专辑可以有很多艺术家.专辑和艺术家当然用于说明,我有真实世界的类型..
可能有一个简单的解决方案,但我有一段时间没有找到它,所以我呼吁这个网站代表的集体大脑来解决它.:)如果不存在简单的解决方案,也欢迎使用复杂的解决方案.
在Album类中或作为以Album作为参数的实用程序方法:
Artist getArtist(); // ok
List<Artist> getArtist(); // Not ok, since we now have many "keys" for every Album
Run Code Online (Sandbox Code Playgroud)
干杯,Mikael Grev
我以为我已经很擅长 Java 8 流了,但后来……
我有一个Foo界面:
public interface Foo {
String getKey();
Stream<Bar> bars();
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用每个键Stream<Foo>将 a收集到 aMap<String, Foo>中:
Map<String, Foo> foosByKey = fooStream.collect(
Collectors.toMap(Foo::getKey, Function.identity()));
Run Code Online (Sandbox Code Playgroud)
但是如果我想将它们收集到一个Map<Bar, Foo>? 换句话说,对于FooSteamFoo中的每一个,我想把它放在映射到Bar由Foo.bars(). 我从哪里开始?
java ×3
java-8 ×2
java-stream ×2
collect ×1
collectors ×1
grouping ×1
key ×1
lambda ×1
mapreduce ×1