Java 8 List<V> 到 Map<K, V>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20363719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 01:24:00  来源:igfitidea点击:

Java 8 List<V> into Map<K, V>

javalambdajava-8java-stream

提问by Tom Cammann

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

我想使用 Java 8 的流和 lambda 将对象列表转换为 Map。

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 lambdas 的 Guava。

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

采纳答案by zapl

Based on Collectorsdocumentationit's as simple as:

根据Collectors文档,它很简单:

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

回答by Ulises

If your key is NOTguaranteed 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>

如果不能保证您的键对于列表中的所有元素都是唯一的,则应将其转换为 aMap<String, List<Choice>>而不是 aMap<String, Choice>

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

回答by Ole

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

使用getName()的关键和Choice本身作为地图的价值:

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

回答by user2069723

I use this syntax

我使用这种语法

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

回答by iZian

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::localMethodNameto actually work because of typing issues.

我试图这样做并发现,使用上面的答案,当Functions.identity()用于映射的键时,this::localMethodName由于键入问题,我在使用本地方法时遇到了问题,例如实际工作。

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

Functions.identity()在这种情况下实际上对打字做了一些事情,所以该方法只能通过返回Object和接受一个参数来工作Object

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

为了解决这个问题,我最终放弃Functions.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));

回答by Kumar Abhishek

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

回答by John McClean

If you don't mind using 3rd party libraries, AOL's cyclops-reactlib (disclosure I am a contributor) has extensions for all JDK Collectiontypes, including Listand Map.

如果您不介意使用 3rd 方库,AOL 的cyclops-reactlib(披露我是贡献者)具有所有JDK 集合类型的扩展,包括ListMap

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

回答by Emre Colak

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

回答by Renukeswar

One more option in simple way

一种简单的方法

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

回答by user_3380739

Here is solution by StreamEx

这是StreamEx 的解决方案

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