我想展平一个Map
将Integer
键关联到的列表的a
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
将值展平到一个新的流中,但是由于仍然需要原始键来收集到中Map
,因此您必须映射到一个包含键和值的临时对象,例如
Map<String, Integer> mapTo = mapFrom.entrySet().stream()
.flatMap(e->e.getValue().stream()
.map(v->new AbstractMap.SimpleImmutableEntry<>(e.getKey(), v)))
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
的Map.Entry
是一个独立的为不存在的元组类型,能够保持不同类型的两个对象的任何其它类型的是足够的。
不需要这些临时对象的替代方法是自定义收集器:
Map<String, Integer> mapTo = mapFrom.entrySet().stream().collect(
HashMap::new, (m,e)->e.getValue().forEach(v->m.put(v, e.getKey())), Map::putAll);
这不同于toMap
静默覆盖重复键,而toMap
如果没有重复键,则没有合并功能将引发异常。基本上,此自定义收集器是
Map<String, Integer> mapTo = new HashMap<>();
mapFrom.forEach((k, l) -> l.forEach(v -> mapTo.put(v, k)));
但是请注意,即使输入图非常大,此任务也不会从并行处理中受益。只有在流管道中还有其他可以从SMP中受益的计算密集型任务时,才有可能从并行流中受益。因此,也许简洁的顺序Collection
API解决方案是可取的。
问题内容: 我怎么能展平的(同类型)s到一个用Java 8? 问题答案: 我的语法可能有些偏离,但是flatMap应该为您完成大部分工作:
问题内容: 我目前的理解非常模糊,我倾向于认为map是同步的,而flatMap是异步的,但是我真的无法解决它。 这是一个例子: 我有文件(a ),我想将其复制到服务器上的某些文件中。 本示例摘自一本书。 我可以将所有更改为to ,反之亦然,一切仍然正常。我不知道有什么区别。 问题答案: 用于同步,非阻塞,一对一转换 用于异步(非阻塞)1-to-N转换 区别在方法签名中可见: 取a 并返回a 取a
问题内容: 我有一个Map是一个到值列表的映射,但是我需要将其求逆,以便 变成 例如我有 我想看看 除了要遍历映射条目并创建set条目(如果不存在)并添加到列表等之外,Java 8中还有什么更简单的方法可以做到这一点?我一直认为这确实很明显,但我无法解决。 提前致谢 问题答案: 未经测试,但是您可以执行以下操作:
我已经找到了很多关于RxJava的答案,但我想了解它在Reactor中是如何工作的。 我目前的理解是非常模糊的,我倾向于认为map是同步的,flatMap是异步的,但我不能真正理解它。 以下是一个例子: 我有文件(a
问题内容: 如何转换 为? 这不起作用: 问题答案: 如果您只包含,则可以这样操作: 如果不是,则可以替换 为。
在闪光灯下,平面图也可以发出一条记录。似乎平面图可以代替地图。有人能告诉我这种情况下的区别吗?谢谢你。