如何分组为数组映射? [英] How to group into map of arrays?

查看:46
本文介绍了如何分组为数组映射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在流上执行groupingBy操作是否可以生成一个值是数组而不是列表或其他集合类型的映射?

Can a groupingBy operation on a stream produce a map where the values are arrays rather than lists or some other collection type?

例如:我有一个课程Thing.事物具有所有者,因此Thing具有getOwnerId方法.在事物流中,我想按所有者ID对事物进行分组,以使具有相同所有者ID的事物以数组的形式结束.换句话说,我想要一个类似以下的映射,其中的键是所有者ID,值是属于该所有者的事物的数组.

For example: I have a class Thing. Things have owners, so Thing has a getOwnerId method. In a stream of things I want to group the things by owner ID so that things with the same owner ID end up in an array together. In other words I want a map like the following where the keys are owner IDs and the values are arrays of things belonging to that owner.

    Map<String, Thing[]> mapOfArrays;

对于我来说,由于我需要将映射值传递给需要数组的库方法,因此将其收集到Map<String, Thing[]>中将是最方便的.

In my case, since I need to pass the map values to a library method that requires an array, it would be most convenient to collect into a Map<String, Thing[]>.

将整个流收集到一个数组中很容易(它甚至不需要显式的收集器):

Collecting the whole stream into one array is easy (it doesn’t even require an explicit collector):

    Thing[] arrayOfThings = Stream.of(new Thing("owner1"), new Thing("owner2"), new Thing("owner1"))
            .toArray(Thing[]::new);

[属于owner1,属于owner2,属于owner1]

[Belongs to owner1, Belongs to owner2, Belongs to owner1]

通过所有者ID进行种植也很容易.例如,要分组到列表中:

Groping by owner ID is easy too. For example, to group into lists:

    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]}

{owner1=[Belongs to owner1, Belongs to owner1], owner2=[Belongs to owner2]}

仅此示例为我提供了列表的映射.有2-arg和3-arg groupingBy方法可以为我提供其他集合类型(如集合)的映射.我认为,如果我可以将收集到数组中的收集器(类似于上面第一个片段中的收集器)传递给两个参数Collectors.groupingBy​(Function<? super T,? extends K>, Collector<? super T,A,D>),则会被设置.但是,Collectors类中的所有预定义收集器似乎都没有对数组做任何事情.我是否错过了一种不太复杂的方法?

Only this example gives me a map of lists. There are 2-arg and 3-arg groupingBy methods that can give me a map of other collection types (like sets). I figured, if I can pass a collector that collects into an array (similar to the collection into an array in the first snippet above) to the two-arg Collectors.groupingBy​(Function<? super T,? extends K>, Collector<? super T,A,D>), I’d be set. However, none of the predefined collectors in the Collectors class seem to do anything with arrays. Am I missing a not too complicated way through?

为完整的示例,这是我在以上代码段中使用的类:

For the sake of a complete example, here’s the class I’ve used in the above snippets:

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;
    }

}

推荐答案

您可以先进行分组,然后使用后续的toMap:

you could group first then use a subsequent toMap:

Map<String, Thing[]> result = source.stream()
                .collect(groupingBy(Thing::getOwnerId))
                .entrySet()
                .stream()
                .collect(toMap(Map.Entry::getKey,
                        e -> e.getValue().toArray(new Thing[0])));

这篇关于如何分组为数组映射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆