如何使用java streams api将层次映射转换为平面映射
因此,我有一个函数,它接受一个映射,其中一个名称与数组中的一个不同索引相关联。索引编号将只有一个与之关联的名称,因此没有重复项,也没有空值,因此使用以下函数可以安全地展平层次结构如何使用java streams api将层次映射转换为平面映射,java,stream,java-stream,Java,Stream,Java Stream,因此,我有一个函数,它接受一个映射,其中一个名称与数组中的一个不同索引相关联。索引编号将只有一个与之关联的名称,因此没有重复项,也没有空值,因此使用以下函数可以安全地展平层次结构 public Map<Integer, Object> normalize( Map<Object, List<Integer>> hierarchalMap ) { Map<Integer, Object> normalizedMap = new HashMa
public Map<Integer, Object> normalize( Map<Object, List<Integer>> hierarchalMap ) {
Map<Integer, Object> normalizedMap = new HashMap<>();
for (Map.Entry<Object, List<Integer>> entry : hierarchalMap.entrySet()) {
for (Integer integer : entry.getValue()) {
noramizedMap.put(integer, entry.getKey());
}
}
return normalizedMap;
}
公共映射规范化(映射层次结构映射){
Map normalizedMap=newhashmap();
for(Map.Entry:hierarchalMap.entrySet()){
for(整数:entry.getValue()){
noramizedMap.put(整数,entry.getKey());
}
}
返回规范化地图;
}
我试图将此函数改为使用streams API,我已经做到了这一点:
Map<Integer, Object> noramizedMap = new HashMap<>();
for (Map.Entry<Object, List<Integer>> entry : vars.entrySet()) {
entry.getValue().forEach(e -> noramizedMap.put(e, entry.getValue()));
}
Map noramizedMap=newhashmap();
对于(Map.Entry:vars.entrySet()){
entry.getValue().forEach(e->noramizedMap.put(e,entry.getValue());
}
如果这是其他函数式语言,我会进行部分绑定或其他操作,但使用java,我会尝试将外部循环展开成一个流……我只是迷路了 假设我的评论是正确的,您可以这样处理流:
hierarchalMap.entrySet()
.stream()
.flatMap(entry -> entry.getValue()
.stream()
.map(i -> new AbstractMap.SimpleEntry<>(entry.getKey(), i)))
.collect(Collectors.toMap(Entry::getValue, Entry::getKey));
hierarchalMap.entrySet()
.stream()
.flatMap(条目->条目.getValue()
.stream()
.map(i->new AbstractMap.SimpleEntry(entry.getKey(),i)))
.collect(Collectors.toMap(条目::getValue,条目::getKey));
这假定没有重复项,也没有空值 假设我的评论是正确的,您可以这样处理流:
hierarchalMap.entrySet()
.stream()
.flatMap(entry -> entry.getValue()
.stream()
.map(i -> new AbstractMap.SimpleEntry<>(entry.getKey(), i)))
.collect(Collectors.toMap(Entry::getValue, Entry::getKey));
hierarchalMap.entrySet()
.stream()
.flatMap(条目->条目.getValue()
.stream()
.map(i->new AbstractMap.SimpleEntry(entry.getKey(),i)))
.collect(Collectors.toMap(条目::getValue,条目::getKey));
这假定没有重复项,也没有空值 我认为这应该满足您的需要:
public Map<Integer, Object> normalizeJava8(Map<Object, List<Integer>> hierarchalMap ) {
return hierarchalMap
.entrySet()
.stream()
.collect(
HashMap::new,
(map, entry) ->
entry.getValue().forEach(i -> map.put(i, entry.getKey())),
HashMap::putAll);
}
公共地图规范化ejava8(地图层次地图){
返回层次结构图
.entrySet()
.stream()
.收集(
HashMap::新建,
(地图,条目)->
entry.getValue().forEach(i->map.put(i,entry.getKey()),
HashMap::putAll);
}
在使用Java8流时,通常需要在操作的“collect”部分比在另一种语言的等效构造中放入更多的逻辑,部分原因是缺少方便的元组类型。直观地说,创建一个配对列表然后将它们收集到一个映射中似乎更明智,但这最终会比将该逻辑放入
中更需要代码和计算。收集我认为这应该满足您的需要:
public Map<Integer, Object> normalizeJava8(Map<Object, List<Integer>> hierarchalMap ) {
return hierarchalMap
.entrySet()
.stream()
.collect(
HashMap::new,
(map, entry) ->
entry.getValue().forEach(i -> map.put(i, entry.getKey())),
HashMap::putAll);
}
公共地图规范化ejava8(地图层次地图){
返回层次结构图
.entrySet()
.stream()
.收集(
HashMap::新建,
(地图,条目)->
entry.getValue().forEach(i->map.put(i,entry.getKey()),
HashMap::putAll);
}
在使用Java8流时,通常需要在操作的“collect”部分比在另一种语言的等效构造中放入更多的逻辑,部分原因是缺少方便的元组类型。直观地说,创建一个对列表然后将它们收集到一个映射中似乎更明智,但这最终会比将该逻辑放入中更需要代码和计算。使用streams和Java 9收集:
Map<Integer, Object> normalizedMap = hierarchalMap.entrySet().stream()
.flatMap(e -> e.getValue().stream().map(i -> Map.entry(i, e.getKey())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
使用streams和Java 9:
Map<Integer, Object> normalizedMap = hierarchalMap.entrySet().stream()
.flatMap(e -> e.getValue().stream().map(i -> Map.entry(i, e.getKey())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
这里有两个可以在Java8中使用的方便收集器,它们不仅限于地图
public static <T, K, V> Collector<T, ?, Map<K, V>> flatInverseMapping(Function<? super T, ? extends Stream<? extends K>> keyStreamFunction,
Function<? super T, ? extends V> valueFunction) {
return Collector.of(HashMap::new,
(m, v) ->
keyStreamFunction.apply(v).forEach(innerV -> m.put(innerV, valueFunction.apply(v))),
(m1, m2) -> {
m1.putAll(m2);
return m2;
});
}
public static <T, K, V> Collector<T, ?, Map<K, V>> flatInverseMapping(Function<? super T, ? extends Collection<? extends K>> keyStreamFunction,
Function<? super T, ? extends V> valueFunction) {
return Collector.of(HashMap::new,
(m, v) ->
keyStreamFunction.apply(v).forEach(innerV -> m.put(innerV, valueFunction.apply(v))),
(m1, m2) -> {
m1.putAll(m2);
return m2;
});
}
publicstaticcollector flatInverseMapping(Function这里有两个方便的收集器,您可以在Java8中使用,它们不仅限于映射
public static <T, K, V> Collector<T, ?, Map<K, V>> flatInverseMapping(Function<? super T, ? extends Stream<? extends K>> keyStreamFunction,
Function<? super T, ? extends V> valueFunction) {
return Collector.of(HashMap::new,
(m, v) ->
keyStreamFunction.apply(v).forEach(innerV -> m.put(innerV, valueFunction.apply(v))),
(m1, m2) -> {
m1.putAll(m2);
return m2;
});
}
public static <T, K, V> Collector<T, ?, Map<K, V>> flatInverseMapping(Function<? super T, ? extends Collection<? extends K>> keyStreamFunction,
Function<? super T, ? extends V> valueFunction) {
return Collector.of(HashMap::new,
(m, v) ->
keyStreamFunction.apply(v).forEach(innerV -> m.put(innerV, valueFunction.apply(v))),
(m1, m2) -> {
m1.putAll(m2);
return m2;
});
}
公共静态收集器平面反向映射(function你的意思是hierarchalMap==vars
实际上?并且有一个normalizedMap
?因为现有的方法不会compile@EugeneDoh!是的--修复了。您仍然有noramizedMap
和normalizedMap
您的意思是hierarchalMap==vars
实际上?还有一个normalizedMapedMap
?因为现有的方法不会compile@EugeneDoh!是的--已修复。您仍然有noramizedMap
和normalizedMap
是否有任何方法可以在collect中执行flatmapping?(只是问一下,尽管它可能看起来很复杂)是否有类似于hierarchalMap.entrySet().stream()的方法。collect(…)
-将所有逻辑放在collect中?谢谢。当我问这个问题时,另一个答案不在那里;)。但我觉得这不是Java 8的方式,因为它正在改变一个映射。想法?@user7你认为收集器如何工作?(提示:它改变了一个映射)嗯……是的。同意。有没有办法在collect中进行平面映射?(只是问一下,虽然它可能看起来很复杂)有没有一种方法像hierarchalMap.entrySet().stream().collect(…)
-将所有逻辑放在collect中?谢谢。当我问这个问题时,另一个答案不在那里;)。但我觉得这不是一种真正的Java 8方法,因为它正在改变映射。想法?@user7你认为收集器.toMap
是如何工作的?(提示:它改变了地图)嗯……是的。同意。有很多正确答案——但这是今天最好的答案。有很多正确答案——但这是今天最好的答案。