如何反转贴图<;v1,设置<;v2>&燃气轮机;映射<;v2,设置<;v1>&燃气轮机;在Java中使用stream()进行编程
我有一个Map对象如何反转贴图<;v1,设置<;v2>&燃气轮机;映射<;v2,设置<;v1>&燃气轮机;在Java中使用stream()进行编程,java,java-8,java-stream,Java,Java 8,Java Stream,我有一个Map对象Map,我想进入集合并将集合中的t2转换为新地图的键。原始键t1将是映射的新值。 例如,给定一个包含两个条目的映射 {key1: [a, b, c], key2: [c, d]} 生成的地图将是 {a: [key1], b: [key1], c: [key1, key2], d: [key2]} []表示上述示例中的集合。一种方法可以是- Map<V1,Set<V2>> inputHashMap = new HashMap<>(); //
Map
,我想进入集合并将集合中的t2
转换为新地图的键。原始键t1
将是映射的新值。例如,给定一个包含两个条目的映射
{key1: [a, b, c], key2: [c, d]}
生成的地图将是
{a: [key1], b: [key1], c: [key1, key2], d: [key2]}
[]表示上述示例中的集合。一种方法可以是-
Map<V1,Set<V2>> inputHashMap = new HashMap<>(); // initialized with your input
Map<V2,Set<V1>> outputHashMap = new HashMap<>();
inputHashMap.forEach((val, keys) -> keys.forEach(key -> {
if (outputHashMap.containsKey(key)) {
outputHashMap.get(key).add(val);
} else {
outputHashMap.put(key, new HashSet<>() {{
add(val);
}});
}
}));
Map inputHashMap=newhashmap();//用您的输入初始化
Map outputHashMap=新HashMap();
inputHashMap.forEach((val,keys)->keys.forEach(key->{
if(outputHashMap.containsKey(键)){
outputHashMap.get(key).add(val);
}否则{
put(key,new HashSet()){{
添加(val);
}});
}
}));
Java 8:
map.entrySet()
.stream()
.flatMap(e -> e.getValue()
.stream()
.map(v -> new SimpleEntry<>(v, e.getKey())))
.collect(Collectors.groupingBy(Entry::getKey,
Collectors.mapping(Entry::getValue, Collectors.toSet())))
:
一种方法可以是:
private static <T1,T2> Map<T1, Set<T2>> invertMap(Map<T2, Set<T1>> data) {
Map<T1, Set<T2>> output = data.entrySet().stream().collect(() -> new HashMap<T1, Set<T2>>(),
(mapLeft, leftEntry) -> {
for (T1 i : leftEntry.getValue()) {
Set<T2> values = mapLeft.get(i);
if (values == null)
values = new HashSet<>();
values.add(leftEntry.getKey());
mapLeft.put(i, values);
}
}, (mapLeft, mapRight) -> mapLeft.putAll(mapRight));
return output;
}
私有静态地图(地图数据){
映射输出=data.entrySet().stream().collect(()->new HashMap(),
(mapLeft,leftEntry)->{
对于(T1 i:leftEntry.getValue()){
设置值=mapLeft.get(i);
如果(值==null)
值=新的HashSet();
add(leftEntry.getKey());
mapLeft.put(i,值);
}
},(mapLeft,mapRight)->mapLeft.putAll(mapRight));
返回输出;
}
使用流(可能有利于使用流上的parallel()
进行并行处理)
少LOC
Map<String, Set<String>> outMap = new HashMap<>();
inMap.forEach((k, v) -> v.forEach(e ->
outMap.computeIfAbsent(e, __ -> new HashSet<>()).add(k)));
Map outMap=newhashmap();
inMap.forEach((k,v)->v.forEach(e->
computeIfAbsent(e,_u->newhashset()).add(k));
你说得对。我刚刚编辑了这个问题。OP请求流;这基本上只是一个嵌套循环。无论哪种方式,都可以使中间部分更干净:Set values=outputHashMap.get(key);if(values==null)outputHashMap.put(key,values=newhashset());值。添加(val)
@shmosel Ya遗漏了问题陈述的steam()
部分。也不想在循环中初始化设置值
,因此是当前的解决方案。代码的Java8版本给出了问题中给定数据的“Duplicate key Key2”异常。
private static <T1,T2> Map<T1, Set<T2>> invertMap(Map<T2, Set<T1>> data) {
Map<T1, Set<T2>> output = data.entrySet().stream().collect(() -> new HashMap<T1, Set<T2>>(),
(mapLeft, leftEntry) -> {
for (T1 i : leftEntry.getValue()) {
Set<T2> values = mapLeft.get(i);
if (values == null)
values = new HashSet<>();
values.add(leftEntry.getKey());
mapLeft.put(i, values);
}
}, (mapLeft, mapRight) -> mapLeft.putAll(mapRight));
return output;
}
Map<String, Set<String>> inMap = new HashMap<>();
inMap.put("key1", new HashSet<>(Arrays.asList("a", "b", "c")));
inMap.put("key2", new HashSet<>(Arrays.asList("c", "d")));
Map<String, Set<String>> outMap = inMap.entrySet().stream().collect(
HashMap::new,
(m, e) -> e.getValue().forEach(v -> m.computeIfAbsent(v, ignore -> new HashSet<>())
.add(e.getKey())),
(m1, m2) -> m2.forEach((key, value) -> m1.merge(key, value,
(s1, s2) -> { s1.addAll(s2); return s1; })));
System.out.println(outMap);
// {a=[key1], b=[key1], c=[key1, key2], d=[key2]}
Map<String, Set<String>> outMap = new HashMap<>();
for (Entry<String, Set<String>> e : inMap.entrySet())
for (String v : e.getValue())
outMap.computeIfAbsent(v, key -> new HashSet<>()).add(e.getKey());
Map<String, Set<String>> outMap = new HashMap<>();
inMap.forEach((k, v) -> v.forEach(e ->
outMap.computeIfAbsent(e, __ -> new HashSet<>()).add(k)));