Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Streams: List to Map with mapped values

Tags:

java-stream

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();
    }
}
like image 766
lilalinux Avatar asked Mar 09 '23 11:03

lilalinux


1 Answers

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.

like image 133
Ole V.V. Avatar answered Mar 15 '23 22:03

Ole V.V.