我在表单中有两个 HashMap
Map<Integer, Map<String,Double>> MAP_1
Map<Integer, Map<String,Double>> MAP_2
让 INNER 成为内部映射,即
Map<String,Double>
对于每对对应的键,我想在两个内部映射之间执行一个操作(例如减法)。反过来,应该在内部映射的两个相应键之间执行此操作。 生成的 map 应该是
Map<Integer,List<Double> RESULT
示例 map 是
MAP_1
------------------------------
| | 2016-10-02 10.0 |
| ID1 | 2016-10-03 20.0 |
| | 2016-10-04 30.0 |
------------------------------
| | 2016-10-02 1.00 |
| ID2 | 2016-10-03 2.00 |
| | 2016-10-04 3.00 |
------------------------------
MAP_2
------------------------------
| | 2016-10-02 2.00 |
| ID1 | 2016-10-03 3.00 |
| | |
------------------------------
| | 2016-10-02 1.00 |
| ID3 | 2016-10-03 2.00 |
| | 2016-10-04 3.00 |
------------------------------
RESULT
---------------
| | 8.00 |
| ID1 | 17.0 |
| | |
---------------
因此,对于外部 map ,只需考虑 ID1;反过来,该操作必须涉及内部(公共(public))键“2016-10-02”和“2016-10-03”。
这是我当前的代码
Set<Integer> common_keys = new LinkedHashSet<Integer>(map1.keySet());
common_keys.retainAll(map2.keySet());
System.out.println("Common keys: "+common_keys.toString());
map1.forEach((k,v) -> {
Map<String,Double> submap_1 = new LinkedHashMap<String,Double>(v);
Map<String,Double> submap_2 = new LinkedHashMap<String,Double>(map2.get(k));
Set<String> commons = new LinkedHashSet<String>(submap_1.keySet());
commons.retainAll(submap_2.keySet());
System.out.println(k+" : common days: "+commons);
List<Double> val1 = submap_1.keySet()
.stream()
.filter(c -> commons.contains(c))
.map(c -> submap_1.get(c))
.collect(Collectors.toList());
List<Double> val2 = submap_2.keySet()
.stream()
.filter(c -> commons.contains(c))
.map(c -> submap_2.get(c))
.collect(Collectors.toList());
List<Double> ABS = IntStream.range(0, val1.size())
.mapToObj(i -> val1.get(i) - val2.get(i))
.collect(Collectors.toList());
diff_abs.put(k, ABS);
});
是否有一种更简单、更智能的方法来做到这一点,即使用 JAVA 8' STREAM API?
提前致谢
最佳答案
创建 Set
是不必要的。将其替换为检查另一张 map 中相同键的 null
。此外,创建 map 的副本是不必要的,因为 map 永远不会在该方法中被修改。
public static <T, U> Map<T, List<Double>> merge(Map<T, Map<U, Double>> m1, Map<T, Map<U, Double>> m2) {
Map<T, List<Double>> result = new HashMap<>();
m1.forEach((k, v) -> {
Map<U, Double> v2 = m2.get(k);
if (v2 != null) {
// both outer maps contain the same key
ArrayList<Double> list = new ArrayList<>();
v.forEach((innerK, innerV) -> {
Double d = v2.get(innerK);
if (d != null) {
// matching key in both inner maps
list.add(innerV - d);
}
});
// list.trimToSize();
result.put(k, list);
}
});
return result;
}
关于java - 使用 STREAM API 在两个 HashMap 之间执行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39870529/