【发布时间】:2018-12-09 17:49:44
【问题描述】:
流上的groupingBy 操作能否生成一个映射,其中值是数组,而不是列表或其他一些集合类型?
例如:我有一个班级Thing。事物有所有者,所以Thing 有一个getOwnerId 方法。在事物流中,我想按所有者 ID 对事物进行分组,以便具有相同所有者 ID 的事物最终一起出现在一个数组中。换句话说,我想要一个像下面这样的地图,其中键是所有者 ID,值是属于该所有者的事物的数组。
Map<String, Thing[]> mapOfArrays;
就我而言,由于我需要将映射值传递给需要数组的库方法,因此收集到Map<String, Thing[]> 是最方便的。
将整个流收集到一个数组中很容易(甚至不需要显式收集器):
Thing[] arrayOfThings = Stream.of(new Thing("owner1"), new Thing("owner2"), new Thing("owner1"))
.toArray(Thing[]::new);
[属于owner1,属于owner2,属于owner1]
按所有者 ID 搜索也很容易。例如,分组到列表中:
Map<String, List<Thing>> mapOfLists = Stream.of(new Thing("owner1"), new Thing("owner2"), new Thing("owner1"))
.collect(Collectors.groupingBy(Thing::getOwnerId));
{owner1=[属于 owner1, 属于 owner1], owner2=[属于 owner2]}
只有这个例子给了我一个列表的地图。有 2-arg 和 3-arg groupingBy 方法可以为我提供其他集合类型(如集合)的映射。我想,如果我可以将收集到数组中的收集器(类似于上面第一个 sn-p 中的收集到数组中)传递给两个参数 Collectors.groupingBy(Function<? super T,? extends K>, Collector<? super T,A,D>),我会被设置。但是,Collectors 类中的预定义收集器似乎都没有对数组做任何事情。我错过了一个不太复杂的方法吗?
为了一个完整的例子,这是我在上面的 sn-ps 中使用的类:
public class Thing {
private String ownerId;
public Thing(String ownerId) {
this.ownerId = ownerId;
}
public String getOwnerId() {
return ownerId;
}
@Override
public String toString() {
return "Belongs to " + ownerId;
}
}
【问题讨论】:
-
处理泛型时处理数组从未更方便。 There's already existing pain out there regarding generic arrays,因此新的 API 会很好地避开数组并转而使用集合。
标签: java arrays java-stream grouping