【问题标题】:How can I add each element of one array to another one's corresponding element using a ParallelStream?如何使用 ParallelStream 将一个数组的每个元素添加到另一个数组的对应元素?
【发布时间】:2014-07-07 22:16:14
【问题描述】:

使用示例可能更容易解释我正在尝试做的事情。假设我必须关注两个数组:

int firstArray[] = {1, 2, 3, 4, 5};
int secArray[] = {1, 2, 3, 4, 5};

我想要的是将第二个数组的每个元素 i 添加到第一个数组的每个元素 i 中。当然,创建第三个数组也是可以的。

在这个例子中,结果是:2, 4, 6, 8, 10

我可以在 Java 8 中使用 ParallelStream 以某种方式做到这一点吗?我只能想到使用至少一个索引的解决方案,并且由于并行性(这也违背了目的),它们并没有真正起作用。

这种单线程方法有效:

AtomicInteger i = new AtomicInteger(0);
int resultArray[] = Arrays.stream(firstArray)
                          .map(a -> a + secArray[i.getAndIncrement()]).toArray();

但如果我尝试使用并行流,结果(当然它们是)随机的并且程序真的很慢。有任何想法吗?

【问题讨论】:

    标签: java arrays java-8


    【解决方案1】:

    这是IntStream 的典型用例:

    IntStream.range(0, firstArray.length).parallel()
        .forEach(i -> { secArray[i] += firstArray[i]; });
    

    如果您需要将结果放在单独的数组中,您可以使用相同的方法:

    int[] result = IntStream.range(0, firstArray.length).parallel()
        .map(i -> firstArray[i] + secArray[i])
        .toArray();
    

    【讨论】:

    • 我不确定您的第二种方法是否保留了当前方法中的顺序。我不这么认为,除非toArray() 保证这一点。您可以通过首先创建数组然后使用与第一个示例类似的方法来解决它。
    • @skiwi:我同意,IntStream::toArray 的文档并不清楚这个问题。但是,根据 fork-join 算法的工作方式,如果不保留顺序,那就太令人惊讶了。
    • 另一种选择是Arrays.parallelSetAll(result, i -> first[i] + second[i])。虽然不使用流,但最终可能会更快。
    猜你喜欢
    • 1970-01-01
    • 2021-03-20
    • 2015-08-15
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多