Java 8流:使用映射值列表映射到
问题描述:
我试图使用Stream
s从List
创建Map
。Java 8流:使用映射值列表映射到
的key
应该是原始项目的名称,
的value
应该是一些派生的数据。
.map()
后的数据流由Integer
S和在.collect()
的时候,我不能从以前lambda
访问“富”。我如何获得.toMap()
中的原始项目?
这可以用Stream
s完成吗?还是需要.forEach()
?
(以下代码仅用于演示,实际代码当然要复杂得多,我不能使doSomething()
为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();
}
}
答
在我看来,这并不复杂。我错过了什么吗?
return Stream.of(new Foo())
.collect(Collectors.toMap(Foo::getName, this::doSomething));
我非常喜欢方法引用。如果你喜欢->
符号,使用
return Stream.of(new Foo())
.collect(Collectors.toMap(foo -> foo.getName(), foo -> doSomething(foo)));
要么将打破(抛出异常),如果有一个以上的Foo
你流的相同名称。
啊我看,所以转换不是用.map()完成的,而是在收集阶段? – lilalinux
我不确定这是否是唯一的选择,但我相信这是在这种情况下做收集器内部映射的最简单的解决方案。 @lilalinux –
花了我几秒钟才明白为什么'new Foo()'应该是一个数组。如果你想要一个单一的元素流,你可以直接使用'Stream.of(new Foo())'而不会让读者感到困惑...... – Holger