如果我根据某个最大值或最小值筛选一个排序集或映射,Java 8会不加考虑地检查每个元素的条件,还是使用“排序”进行优化?如果没有,是否有更好的方法仍然使用Java 8并行?
SortedSet<Integer> numbers = getNumbers();
numbers.parallelStream().filter(n -> n <= 100).forEach(...);
按要求澄清:让我们假设“数字”很大。如果我们检查每个元素,如果它是<= 100 (或任何其他数字),我们会浪费大量的时间。一个有效的实现将二进制搜索在排序的集合上,并在日志时间而不是线性时间中识别截止值,然后使用一些内部集特性来在这个截止时间创建一个子集。
发布于 2014-02-16 15:48:51
结合并行流使用headSet方法。在您的示例中,如下所示:
SortedSet<Integer> numbers = getNumbers();
numbers.headSet(100 + 1)
.parallelStream()
.filter(n -> n <= 100) // no longer required
.forEach(...);
首先,代码以对数复杂度进行二进制搜索。之后,所有小于100 + 1
的元素都会被并行处理。
编辑:不幸的是,TreeSet和ConcurrentSkipListSet都不支持子集上的并行执行。上面的代码将工作,但它将始终按顺序执行。这可以使用下面的代码进行检查。我看不出有什么理由不能这样做。我想没人认为这可能很重要。
SortedSet<Integer> numbers = ...;
System.out.printf("Full Set: %s\nPartial Set: %s\n",
numbers.spliterator().trySplit(),
numbers.headSet(1_000_000).spliterator().trySplit());
发布于 2014-02-16 15:21:49
你能详细解释一下你所说的“一定的最大值或最小值”是什么意思吗?示例代码使用硬编码值100。您是否认为100是应用于SoretedRet的最大或最小函数的结果??或者只是问过滤器是如何应用的?
首先应用过滤器。结果是所有符合筛选标准的元素(<= 100)。
ForEach是应用于筛选结果的结果(即不应用于任何不符合筛选标准的元素)。
SortedSet<Integer> numbers = new TreeSet<Integer>();
for (int index = 0; index < 100; index++) {
numbers.add(index);
}
Stream<Integer> filterResult = numbers.parallelStream().filter(n -> n <= 9);
System.out.println(filterResult.count());
但是,我不知道你在问什么?也许你可以详细说明一下。
更新:请参阅此页面:http://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html
并行执行流 您可以串行或并行地执行流。当流并行执行时,Java运行时将流划分为多个子流。聚合操作迭代并并行处理这些子流,然后组合结果。
该操作将集合划分为并行任务,从而将集合划分为子部分。
此外,您还可以仔细阅读源代码,并验证实现是否符合您的期望。JSR是一个规范权限:)而不是实现。因此,从技术上讲,要回答您的问题,我们需要查看具体的实现。只是要考虑一下。
希望这有帮助:)祝你好运
https://stackoverflow.com/questions/21812623
复制相似问题