【发布时间】:2018-06-27 16:49:47
【问题描述】:
我有一个链接的 hashmap,它最多可以包含 300k 条记录。我想并行迭代这张地图以提高性能。该函数遍历向量映射并找到给定向量与映射中所有向量的点积。还要根据日期值进行另一项检查。该函数返回一个嵌套的哈希图。 T
这是使用迭代器的代码:
public HashMap<String,HashMap<String,Double>> function1(String key, int days) {
LocalDate date = LocalDate.now().minusDays(days);
HashMap<String,Double> ret = new HashMap<>();
HashMap<String,Double> ret2 = new HashMap<>();
OpenMapRealVector v0 = map.get(key).value;
for(Map.Entry<String, FixedTimeHashMap<OpenMapRealVector>> e: map.entrySet()) {
if(!e.getKey().equals(key)) {
Double d = v0.dotProduct(e.getValue().value);
d = Double.parseDouble(new DecimalFormat("###.##").format(d));
ret.put(e.getKey(),d);
if(e.getValue().date.isAfter(date)){
ret2.put(e.getKey(),d);
}
}
}
HashMap<String,HashMap<String,Double>> result = new HashMap<>();
result.put("dot",ret);
result.put("anomaly",ret2);
return result;
}
更新: 我查看了 Java 8 流,但是在使用并行流时遇到了 CastException 和 Null 指针异常,因为该映射正在其他地方进行修改。
代码:
public HashMap<String,HashMap<String,Double>> function1(String key, int days) {
LocalDate date = LocalDate.now().minusDays(days);
HashMap<String,Double> ret = new HashMap<>();
HashMap<String,Double> ret2 = new HashMap<>();
OpenMapRealVector v0 = map.get(key).value;
synchronized (map) {
map.entrySet().parallelStream().forEach(e -> {
if(!e.getKey().equals(key)) {
Double d = v0.dotProduct(e.getValue().value);
d = Double.parseDouble(new DecimalFormat("###.##").format(d));
ret.put(e.getKey(),d);
if(e.getValue().date.isAfter(date)) {
ret2.put(e.getKey(),d);
}
}
});
}
}
我已经同步了地图的使用,但它仍然给我以下错误:
java.util.concurrent.ExecutionException: java.lang.ClassCastException
Caused by: java.lang.ClassCastException
Caused by: java.lang.ClassCastException: java.util.HashMap$Node cannot be cast to java.util.HashMap$TreeNode
另外,我在想我是否应该将地图分成多个部分并使用不同的线程并行运行每个部分?
【问题讨论】:
-
“我研究了 Java 8 流,但无法获得此函数的并行流实现。” 向我们展示您的尝试,以便我们更好地帮助您找出什么你做错了。
-
@Andreas ,我已经更新了问题以显示确切的问题。
-
错误是因为parallel = multi-threaded,并且您在
HashMap上执行多线程ret.put(...),这不是线程安全的对象。将ret和ret2更改为ConcurrentHashMap将解决该问题,然后将返回值更改为Map<String, Map<String, Double>> -
谢谢@Andreras,我一直在考虑各种事情,但从未检查过 ret 和 ret2。这已经解决了问题。
-
Mehdi 接受的解决方案解决了问题中的问题。 Ravindra 的答案是完整的 Java 8 解决方案。
标签: java hashmap java-stream java-threads