java - 并行迭代大哈希图
问题描述
我有一个链接的哈希图,最多可以包含 30 万条记录。我想并行迭代这个地图以提高性能。该函数遍历向量映射并找到给定向量与映射中所有向量的点积。还要根据日期值进行另一项检查。该函数返回一个嵌套的哈希图。吨
这是使用迭代器的代码:
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
另外,我在想我应该将地图分成多个部分并使用不同的线程并行运行每个部分吗?
解决方案
您需要Set<Map.Entry<K, V>>
从地图中检索。
以下是在 Java8 中使用并行流对 Map 进行迭代的方法:
Map<String, String> myMap = new HashMap<> ();
myMap.entrySet ()
.parallelStream ()
.forEach (entry -> {
String key = entry.getKey ();
String value = entry.getValue ();
// here add whatever processing you wanna do using the key / value retrieved
// ret.put (....);
// ret2.put (....)
});
澄清:
映射ret
和ret2
应声明为ConcurrentHashMap
s 以允许来自多个线程的并发插入/更新。
所以这两张地图的声明变成了:
Map<String,Double> ret = new ConcurrentHashMap<> ();
Map<String,Double> ret2 = new ConcurrentHashMap<> ();
推荐阅读
- indexeddb - svelte.dev/repl 似乎不支持 indexedDb(或 localStorage)
- swift - textField 最大长度和邮政编码验证
- javascript - 在 VBA 中使用脚本时出错
- c++ - 计算与异常二维空间中点的角度的函数
- azure - 在 Azure 中,使用 powershell 脚本将负载均衡器详细信息保存到 csv 文件中
- reactjs - Highcharts addPoint 动画
- python - 如何使用python在json文件中查找不完整的数据
- azure - 如何使用 pyodbc 将 pandas 数据帧的多行插入 Azure Synapse SQL DW?
- scala - 使用整数将相同的行添加到 Spark Dataframe
- firebase - 如何从 Firebase 数据库中检索子数据的值?