Java 8 List into Map。

时间:2022-09-23 19:36:22

I want to translate a List of objects into a Map using Java 8's streams and lambdas.

我想用Java 8的流和lambdas将一个对象列表转换成映射。

This is how I would write it in Java 7 and below.

这就是我如何在Java 7和下面编写它的方法。

private Map<String, Choice> nameMap(List<Choice> choices) {
        final Map<String, Choice> hashMap = new HashMap<>();
        for (final Choice choice : choices) {
            hashMap.put(choice.getName(), choice);
        }
        return hashMap;
}

I can accomplish this easily using Java 8 and Guava but I would like to know how to do this without Guava.

我可以很容易地用Java 8和Guava来完成这个任务,但是我想知道如何在没有Guava的情况下做到这一点。

In Guava:

番石榴:

private Map<String, Choice> nameMap(List<Choice> choices) {
    return Maps.uniqueIndex(choices, new Function<Choice, String>() {

        @Override
        public String apply(final Choice input) {
            return input.getName();
        }
    });
}

And Guava with Java 8 lambdas.

和Java 8的番石榴。

private Map<String, Choice> nameMap(List<Choice> choices) {
    return Maps.uniqueIndex(choices, Choice::getName());
}

14 个解决方案

#1


961  

Based on Collectors documentation it's as simple as:

基于收集器的文档,它非常简单:

Map<String, Choice> result =
    choices.stream().collect(Collectors.toMap(Choice::getName,
                                              Function.identity()));

#2


189  

If your key is NOT guaranteed to be unique for all elements in the list, you should convert it to a Map<String, List<Choice>> instead of a Map<String, Choice>

如果您的键不能保证列表中的所有元素都是惟一的,那么您应该将其转换为Map >而不是Map ,选择> ,>

Map<String, List<Choice>> result =
 choices.stream().collect(Collectors.groupingBy(Choice::getName));

#3


99  

Use getName() as the key and choice itself as the value of the map:

使用getName()作为键和选择本身作为映射的值:

Map<String, Choice> result =
    choices.stream().collect(Collectors.toMap(Choice::getName, c -> c));

#4


11  

Here's another one in case you don't want to use Collectors.toMap()

这是另一个,以防你不想使用Collectors.toMap()

Map<String, Choice> result =
   choices.stream().collect(HashMap<String, Choice>::new, 
                           (m, c) -> m.put(c.getName(), c),
                           (m, u) -> {});

#5


10  

If you don't mind to use a 3rd party lib (Vavr(formerly known as Javaslang)) you could use powerful new immutable collections:

如果您不介意使用第三方lib (Vavr(以前称为Javaslang)),您可以使用强大的新不可变集合:

// import javaslang.collection.*;
Map<String, Choice> map = list.toMap(choice -> Tuple.of(choice.getName(), choice));

There are also many methods to convert Java collections forth and back.

还有许多方法可以将Java集合来回转换。

Please read more about the new collections here.

请阅读更多关于这里的新收藏品。

Disclaimer: I'm the creator of Vavr.

免责声明:我是Vavr的创建者。

#6


8  

If you don't mind using 3rd party libraries, AOL's cyclops-react lib (disclosure I am a contributor) has extensions for all JDK Collection types, including List and Map.

如果您不介意使用第三方库,AOL的cyclops-react lib(我是一个贡献者)对所有JDK集合类型都有扩展,包括列表和映射。

ListX<Choices> choices;
Map<String, Choice> map = choices.toMap(c-> c.getName(),c->c);

#7


8  

One more option in simple way

还有一个简单的选择。

Map<String,Choice> map = new HashMap<>();
choices.forEach(e->map.put(e.getName(),e));

#8


7  

I was trying to do this and found that, using the answers above, when using Functions.identity() for the key to the Map, then I had issues with using a local method like this::localMethodName to actually work because of typing issues.

我试图这样做,并发现,在使用函数.identity()作为映射的键时,我使用了这样的本地方法::localMethodName实际上是由于键入问题而工作的。

Functions.identity() actually does something to the typing in this case so the method would only work by returning Object and accepting a param of Object

identity()实际上对这种情况下的类型进行了一些操作,因此该方法只能通过返回对象并接受对象的一个param来工作。

To solve this, I ended up ditching Functions.identity() and using s->s instead.

为了解决这个问题,我放弃了函数。identity()和使用s->s。

So my code, in my case to list all directories inside a directory, and for each one use the name of the directory as the key to the map and then call a method with the directory name and return a collection of items, looks like:

因此,我的代码,在我的例子中列出了目录中的所有目录,对于每个目录,都使用目录的名称作为映射的键,然后调用一个带有目录名的方法并返回一个条目集合,如下所示:

Map<String, Collection<ItemType>> items = Arrays.stream(itemFilesDir.listFiles(File::isDirectory))
.map(File::getName)
.collect(Collectors.toMap(s->s, this::retrieveBrandItems));

#9


4  

I use this syntax

我用这个语法

Map<Integer, List<Choice>> choiceMap = 
choices.stream().collect(Collectors.groupingBy(choice -> choice.getName()));

#10


4  

For example, if you want convert object fields to map:

例如,如果您希望将对象字段转换为映射:

Example object:

例对象:

class Item{
        private String code;
        private String name;

        public Item(String code, String name) {
            this.code = code;
            this.name = name;
        }

        //getters and setters
    }

And operation convert List To Map:

操作转换列表为:

List<Item> list = new ArrayList<>();
list.add(new Item("code1", "name1"));
list.add(new Item("code2", "name2"));

Map<String,String> map = list.stream()
     .collect(Collectors.toMap(Item::getCode(), Item::getName()));

#11


3  

Map<String, Set<String>> collect = Arrays.asList(Locale.getAvailableLocales()).stream().collect(Collectors
                .toMap(l -> l.getDisplayCountry(), l -> Collections.singleton(l.getDisplayLanguage())));

#12


3  

You can create a Stream of the indices using an IntStream and then convert them to a Map :

您可以使用一个IntStream创建一个索引流,然后将它们转换为映射:

Map<Integer,Item> map = 
IntStream.range(0,items.size())
         .boxed()
         .collect(Collectors.toMap (i -> i, i -> items.get(i)));

#13


1  

Here is solution by StreamEx

这里是StreamEx的解决方案。

StreamEx.of(choices).toMap(Choice::getName, c -> c);

#14


-1  

Map<String,Choice> map=list.stream().collect(Collectors.toMap(Choice::getName, s->s));

Even serves this purpose for me,

甚至为我服务,

Map<String,Choice> map=  list1.stream().collect(()-> new HashMap<String,Choice>(), 
            (r,s) -> r.put(s.getString(),s),(r,s) -> r.putAll(s));

#1


961  

Based on Collectors documentation it's as simple as:

基于收集器的文档,它非常简单:

Map<String, Choice> result =
    choices.stream().collect(Collectors.toMap(Choice::getName,
                                              Function.identity()));

#2


189  

If your key is NOT guaranteed to be unique for all elements in the list, you should convert it to a Map<String, List<Choice>> instead of a Map<String, Choice>

如果您的键不能保证列表中的所有元素都是惟一的,那么您应该将其转换为Map >而不是Map ,选择> ,>

Map<String, List<Choice>> result =
 choices.stream().collect(Collectors.groupingBy(Choice::getName));

#3


99  

Use getName() as the key and choice itself as the value of the map:

使用getName()作为键和选择本身作为映射的值:

Map<String, Choice> result =
    choices.stream().collect(Collectors.toMap(Choice::getName, c -> c));

#4


11  

Here's another one in case you don't want to use Collectors.toMap()

这是另一个,以防你不想使用Collectors.toMap()

Map<String, Choice> result =
   choices.stream().collect(HashMap<String, Choice>::new, 
                           (m, c) -> m.put(c.getName(), c),
                           (m, u) -> {});

#5


10  

If you don't mind to use a 3rd party lib (Vavr(formerly known as Javaslang)) you could use powerful new immutable collections:

如果您不介意使用第三方lib (Vavr(以前称为Javaslang)),您可以使用强大的新不可变集合:

// import javaslang.collection.*;
Map<String, Choice> map = list.toMap(choice -> Tuple.of(choice.getName(), choice));

There are also many methods to convert Java collections forth and back.

还有许多方法可以将Java集合来回转换。

Please read more about the new collections here.

请阅读更多关于这里的新收藏品。

Disclaimer: I'm the creator of Vavr.

免责声明:我是Vavr的创建者。

#6


8  

If you don't mind using 3rd party libraries, AOL's cyclops-react lib (disclosure I am a contributor) has extensions for all JDK Collection types, including List and Map.

如果您不介意使用第三方库,AOL的cyclops-react lib(我是一个贡献者)对所有JDK集合类型都有扩展,包括列表和映射。

ListX<Choices> choices;
Map<String, Choice> map = choices.toMap(c-> c.getName(),c->c);

#7


8  

One more option in simple way

还有一个简单的选择。

Map<String,Choice> map = new HashMap<>();
choices.forEach(e->map.put(e.getName(),e));

#8


7  

I was trying to do this and found that, using the answers above, when using Functions.identity() for the key to the Map, then I had issues with using a local method like this::localMethodName to actually work because of typing issues.

我试图这样做,并发现,在使用函数.identity()作为映射的键时,我使用了这样的本地方法::localMethodName实际上是由于键入问题而工作的。

Functions.identity() actually does something to the typing in this case so the method would only work by returning Object and accepting a param of Object

identity()实际上对这种情况下的类型进行了一些操作,因此该方法只能通过返回对象并接受对象的一个param来工作。

To solve this, I ended up ditching Functions.identity() and using s->s instead.

为了解决这个问题,我放弃了函数。identity()和使用s->s。

So my code, in my case to list all directories inside a directory, and for each one use the name of the directory as the key to the map and then call a method with the directory name and return a collection of items, looks like:

因此,我的代码,在我的例子中列出了目录中的所有目录,对于每个目录,都使用目录的名称作为映射的键,然后调用一个带有目录名的方法并返回一个条目集合,如下所示:

Map<String, Collection<ItemType>> items = Arrays.stream(itemFilesDir.listFiles(File::isDirectory))
.map(File::getName)
.collect(Collectors.toMap(s->s, this::retrieveBrandItems));

#9


4  

I use this syntax

我用这个语法

Map<Integer, List<Choice>> choiceMap = 
choices.stream().collect(Collectors.groupingBy(choice -> choice.getName()));

#10


4  

For example, if you want convert object fields to map:

例如,如果您希望将对象字段转换为映射:

Example object:

例对象:

class Item{
        private String code;
        private String name;

        public Item(String code, String name) {
            this.code = code;
            this.name = name;
        }

        //getters and setters
    }

And operation convert List To Map:

操作转换列表为:

List<Item> list = new ArrayList<>();
list.add(new Item("code1", "name1"));
list.add(new Item("code2", "name2"));

Map<String,String> map = list.stream()
     .collect(Collectors.toMap(Item::getCode(), Item::getName()));

#11


3  

Map<String, Set<String>> collect = Arrays.asList(Locale.getAvailableLocales()).stream().collect(Collectors
                .toMap(l -> l.getDisplayCountry(), l -> Collections.singleton(l.getDisplayLanguage())));

#12


3  

You can create a Stream of the indices using an IntStream and then convert them to a Map :

您可以使用一个IntStream创建一个索引流,然后将它们转换为映射:

Map<Integer,Item> map = 
IntStream.range(0,items.size())
         .boxed()
         .collect(Collectors.toMap (i -> i, i -> items.get(i)));

#13


1  

Here is solution by StreamEx

这里是StreamEx的解决方案。

StreamEx.of(choices).toMap(Choice::getName, c -> c);

#14


-1  

Map<String,Choice> map=list.stream().collect(Collectors.toMap(Choice::getName, s->s));

Even serves this purpose for me,

甚至为我服务,

Map<String,Choice> map=  list1.stream().collect(()-> new HashMap<String,Choice>(), 
            (r,s) -> r.put(s.getString(),s),(r,s) -> r.putAll(s));