并行化双嵌套 for 循环

Parallelizing double nested for loop

我有一个非常大的列表,所以我需要加快整体速度,我正在尝试并行化这个 for 循环:

public HashMap<String, String> getData()
{
    //Both list are ArrayList<String>
    HashMap<String, String> hashMap = new HashMap<>();
    for (int w = 0; w < firstList.size(); w++) {
        boolean once = false;
        for (int j = 0; j < secondList.size(); j++) {
            if (!once && secondList.get(j).var.startsWith(firstList.get(w).var.toLowerCase())) {
                hashMap.put(firstList.get(w).var, secondList.get(j).var);
                once = true;
            }
        }
    }
    return hashMap;
}

我找到了这个很好的答案 Parallelizing a for loop,但不太明白如何将它应用到我的案例中,我应该为我的 [=13] 的 <K, V> 创建两个 Callable <output> =] ?

还是我用这个方法做错了?

我会先用流重写它。这不仅会使代码可并行化,还会使其更具可读性。它还将避免原始代码中出现的所有重复,并确保以最佳方式迭代列表:

private static final class Entry {
    private final String first;
    private final String second;

    // constructor, getters left as an exercise
}

public Map<String, String> getData() {
    return firstList.stream()
        .flatMap(firstListElement -> {
            String lowercase = firstListElement.toLowerCase();
            return secondList.stream()
                             .filter(secondListElement -> secondListElement.startsWith(lowercase))
                             .limit(1)
                             .map(secondListElement -> new Entry(firstListElement, secondListElement));
        })
        .collect(Collectors.toMap(Entry::getFirst, Entry::getSecond));   
}

然后我会测量执行它所花费的时间,并比较执行相同代码所花费的时间,但与 firstList.parallelStream() 不同。

像这样的事情会并行完成工作(在外部列表上)。但是对于只有 281 个的列表,这可能不会增加太多价值。

在内部列表中,如果重要的是找到一个匹配项,而不是第一个匹配项,那么该工作也可以并行化,这更有可能产生重大影响。

final ConcurrentMap<String, String> results = new ConcurrentHashMap<>();
firstList.stream()
         .unordered()
         .parallel()
         .map(v1 -> v1.var)
         .forEach(var -> {
             final String lowerVar1 = var.toLowerCase();
             secondList.stream()
                       .filter(v2 -> v2.var.startsWith(lowerVar1))
                       .findFirst()
                       .ifPresent(v2 -> results.put(var, v2.var);
         });

问题不在于如何并行化循环。您使用了错误的方法。
如果我理解正确的话,您希望列表 1 的每个元素都添加列表 2 中以相同字符串开头的 hashmap 1 条目。
首先,我不明白为什么在找到匹配项并使用 once 变量时不跳出循环。
另外为什么你需要 once 变量,因为你可以检查 list1 的单词是否已经存在于 hashmap 中?
无论如何,您应该使用 TreeMap(检查 NavigableMap 接口)而不是检查紧密匹配的哈希图。
另外,为什么你不能在创建列表时首先执行此逻辑?
也许您正在尝试优化错误的东西?