Nik*_*lay 49 java collections dictionary java-8 java-stream
我有一个List<Item>
集合.我需要将其转换Map<Integer, Item>
为映射的键必须是集合中项的索引.我无法弄清楚如何使用流来做到这一点.就像是:
items.stream().collect(Collectors.toMap(...));
Run Code Online (Sandbox Code Playgroud)
有帮助吗?
由于这个问题被确定为可能重复,我需要补充一点,我的具体问题是 - 如何获取列表中项目的位置并将其作为键值
Era*_*ran 50
您可以使用a创建一个Stream
索引IntStream
,然后将它们转换为Map
:
Map<Integer,Item> map =
IntStream.range(0,items.size())
.boxed()
.collect(Collectors.toMap (i -> i, i -> items.get(i)));
Run Code Online (Sandbox Code Playgroud)
Tag*_*eev 12
另一个完整性的解决方案是使用自定义收集器:
public static <T> Collector<T, ?, Map<Integer, T>> toMap() {
return Collector.of(HashMap::new, (map, t) -> map.put(map.size(), t),
(m1, m2) -> {
int s = m1.size();
m2.forEach((k, v) -> m1.put(k+s, v));
return m1;
});
}
Run Code Online (Sandbox Code Playgroud)
用法:
Map<Integer, Item> map = items.stream().collect(toMap());
Run Code Online (Sandbox Code Playgroud)
此解决方案是并行友好的,不依赖于源(您可以使用列表而无需随机访问Files.lines()
或其他).
不要觉得你必须在流中做任何事情.我会这样做:
AtomicInteger index = new AtomicInteger();
items.stream().collect(Collectors.toMap(i -> index.getAndIncrement(), i -> i));
Run Code Online (Sandbox Code Playgroud)
只要您不对流进行并行化,这将起作用,并且它避免了潜在的昂贵和/或有问题(在重复的情况下)get()
和indexOf()
操作.
(您不能使用常规int
变量代替,AtomicInteger
因为从lambda表达式外部使用的变量必须是有效的最终.请注意,当无争议(如本例中)时,AtomicInteger
非常快并且不会造成性能问题.但是如果它担心你可以使用非线程安全的计数器.)
这是更新的答案,没有评论中提到的问题.
Map<Integer,Item> outputMap = IntStream.range(0,inputList.size()).boxed().collect(Collectors.toMap(Function.identity(), i->inputList.get(i)));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
68462 次 |
最近记录: |