java - 并行创建匹配表

标签 java parallel-processing guava java-8

我有两组对象(X,Y),我想将 X 中的所有元素与 Y 中的所有元素进行比较,并将结果值写入匹配表中。

我的第一个方法是必须有两个 for 循环,它们迭代集合并将结果写入表中。

Table<Object, Object, Double>matchTable = TreeBasedTable.create(new ObjectComparator(), new ObjectComparator());

for (Object x : X) {
    for (Object y : Y) {
        double diff = comparator.diff(x, y);
        matchTable.put(x, y, diff);
    }
}

由于 Java 8 有更多并行处理的可能性,我想做同样的事情,但并行。我的第一次尝试看起来像这样,但我认为这不是应该的方式,我认为最好使用一些Collector来创建表并写入它。

Function<Pair<Object>, Boolean> colF = pair -> {
    double diff = comparator.diff(pair.x, pair.y);
    matchTable.put(pair.x, pair.y, diff);
    return true;
};
Function<Object, Long> rowF = x -> {
    return Y.parallelStream().map(y -> {
        return colF.apply(new Pair<Object>(x, y));
    }).count();
};
long count = X.parallelStream().map(rowF).count();

(我只是调用 count(),因为否则它会延迟执行。Pair 只是一个包含两个对象的类。)

最佳答案

这里发生了两件事。第一个是如何将二维迭代线性化为流,第二个是如何将结果存储到某种数据结构中。

将 2D 迭代线性化为流的一个有用习惯是使用行值驱动外部流,并调用 flatMap 返回该行的所有列值的流。这通常需要某种结对结构,但你已经接受了。代码看起来像这样:

X.stream()
 .flatMap(x -> Y.stream().map(y -> new Pair(x, y)))
 .forEach(System.out::println);

这会将所有对生成线性流并将其打印出来。

我不知道Guava的TreeBasedTable是如何工作的。它看起来不是线程安全的,但这没关系,因为流收集器可以处理非线程安全的情况。但是,收集器需要合并中间结果,但我不知道如何使用 Guava Table 对象来做到这一点。其他人必须提供该信息。

如果您想将值收集到按对键控的映射(而不是表格)中,您可以执行以下操作:

X.stream()
 .flatMap(x -> Y.stream().map(y -> new Pair(x, y)))
 .collect(toMap(pair -> pair, pair -> pair.a + pair.b));

如果要并行运行流,则应使用 toConcurrentMap 而不是 toMap

关于java - 并行创建匹配表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23955837/

相关文章:

java - Libgdx - 处理同一 Actor 的不同动画

c++ - OpenMP 中的同步

parallel-processing - 几个带有WAIT的aRFC,如何在回调中同步访问变量?

java - TreeMultimap 不允许 null 或空值?

java - 如何纠正这个目前只抛出异常但我也想返回一个对象的函数?

guava - ceylon 模块系统 : Guava class mismatch even though there's only one Guava in dependencies tree

java - 每 30 秒更新一次订单状态

java - 无法使用适用于 Windows 的 ADT bundle 创建新的 Android 应用程序项目

java - SAX 解析 : Encountered mixed content within text element

scala - 为什么scala的并行序列没有包含方法?