【发布时间】:2017-03-21 23:10:31
【问题描述】:
我想展平一个Map,它将Integer 键与String 列表相关联,而不会丢失键映射。
我很好奇,好像使用 stream 和 lambda 这样做是可能和有用的。
我们从这样的开始:
Map<Integer, List<String>> mapFrom = new HashMap<>();
让我们假设 mapFrom 填充在某个地方,看起来像:
1: a,b,c
2: d,e,f
etc.
我们还假设列表中的值是唯一的。
现在,我想“展开”它以获得第二张地图,例如:
a: 1
b: 1
c: 1
d: 2
e: 2
f: 2
etc.
我可以这样做(或者非常类似,使用foreach):
Map<String, Integer> mapTo = new HashMap<>();
for (Map.Entry<Integer, List<String>> entry: mapFrom.entrySet()) {
for (String s: entry.getValue()) {
mapTo.put(s, entry.getKey());
}
}
现在让我们假设我想使用 lambda 而不是嵌套的 for 循环。我可能会这样做:
Map<String, Integer> mapTo = mapFrom.entrySet().stream().map(e -> {
e.getValue().stream().?
// Here I can iterate on each List,
// but my best try would only give me a flat map for each key,
// that I wouldn't know how to flatten.
}).collect(Collectors.toMap(/*A String value*/,/*An Integer key*/))
我也尝试了flatMap,但我认为这不是正确的方法,因为虽然它帮助我摆脱了维度问题,但我在这个过程中失去了关键。
简而言之,我的两个问题是:
- 是否可以使用
streams和lambda来实现这一点? - 这样做是否有用(性能、可读性)?
【问题讨论】:
-
你肯定想要
flatMap:entrySet.stream().flatMap(e -> e.getValue().stream().map(s -> new SimpleImmutableEntry(e.getKey(), s)) -
@MarkoTopolnik 你的评论应该是一个答案。
-
@MarkoTopolnik 这应该是一个答案
标签: java lambda java-8 java-stream