Java 8 Streams: List to Map with mapped values

纵然是瞬间 提交于 2019-12-01 05:53:18

问题


I'm trying to create a Map from a List using Streams.

The key should be the name of the original item,

The value should be some derived data.

After .map() the stream consists of Integers and at the time of .collect() I can't access "foo" from the previous lambda. How do I get the original item in .toMap()?

Can this be done with Streams or do I need .forEach()?

(The code below is only for demonstration, the real code is of course much more complex and I can't make doSomething() a method of Foo).

import java.util.ArrayList;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class StreamTest {

    public class Foo {
        public String getName() {
            return "FOO";
        }

        public Integer getValue() {
            return 42;
        }
    }

    public Integer doSomething(Foo foo) {
        return foo.getValue() + 23;
    }

    public Map<String, Integer> run() {
        return new ArrayList<Foo>().stream().map(foo -> doSomething(foo)).collect(Collectors.toMap(foo.getName, Function.identity()));
    }

    public static void main(String[] args) {
        StreamTest streamTest = new StreamTest();
        streamTest.run();
    }
}

回答1:


It appears to me it’s not that complicated. Am I missing something?

    return Stream.of(new Foo())
            .collect(Collectors.toMap(Foo::getName, this::doSomething));

I’m rather much into method references. If you prefer the -> notation, use

    return Stream.of(new Foo())
            .collect(Collectors.toMap(foo -> foo.getName(), foo -> doSomething(foo)));

Either will break (throw an exception) if there’s more than one Foo with the same name in your stream.



来源:https://stackoverflow.com/questions/43148509/java-8-streams-list-to-map-with-mapped-values

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!