Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 流并行跳过-链式流方法的顺序有什么不同吗?_Java_Java 8_Java Stream - Fatal编程技术网

Java 流并行跳过-链式流方法的顺序有什么不同吗?

Java 流并行跳过-链式流方法的顺序有什么不同吗?,java,java-8,java-stream,Java,Java 8,Java Stream,vs stream.parallel().skip(1) 这是关于Java8流的。 这两个都跳过了第一行/条目吗 例如: stream.skip(1).parallel() 今天早些时候,我有时会在lambda表达式中得到标题行“a,b,c”。这是一个惊喜,因为我本以为已经跳过了。现在我无法使该示例工作,即,我无法获得lambda表达式中的头行。所以我现在很困惑,也许是其他因素影响了这种行为。当然,这只是一个例子。在现实世界中,消息是从CSV文件读取的。该消息是该CSV文件的完整内容。是

vs

stream.parallel().skip(1) 
这是关于Java8流的。
这两个都跳过了第一行/条目吗

例如:

stream.skip(1).parallel() 
今天早些时候,我有时会在lambda表达式中得到标题行“a,b,c”。这是一个惊喜,因为我本以为已经跳过了。现在我无法使该示例工作,即,我无法获得lambda表达式中的头行。所以我现在很困惑,也许是其他因素影响了这种行为。当然,这只是一个例子。在现实世界中,消息是从CSV文件读取的。该消息是该CSV文件的完整内容。

是,但是
skip(n)
速度较慢,因为
n
在并行流中更大

以下是API注释:

虽然
skip()
通常是顺序流管道上的一种廉价操作,但在有序并行管道上,它可能非常昂贵,尤其是对于
n
的大值,因为
skip(n)
被约束为不仅跳过任何
n
元素,而且跳过相遇顺序中的第一个
n
元素。使用无序流源(例如
generate(Supplier)
)或删除
BaseStream的排序约束。如果您的情况语义允许,无序()
可能会导致并行管道中的
skip()
显著加速。如果需要与遭遇顺序保持一致,并且并行管道中的
skip()
性能或内存利用率较差,则切换到使用
BaseStream的顺序执行。sequential()
可能会提高性能

因此,从本质上讲,如果您希望使用
skip()
获得更好的性能,请不要使用并行流或无序流


至于它似乎不适用于并行流,也许你真的看到元素不再有序了?例如,此代码的输出:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.concurrent.atomic.AtomicLong;

public class Test010 {

    public static void main(String[] args) {
        String message = 
        "a,b,c\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n7,8,9\n";

        try(BufferedReader br = new BufferedReader(new StringReader(message))){

            AtomicLong cnt = new AtomicLong(1);

            br.lines().parallel().skip(1).forEach(
                s -> {
                    System.out.println(cnt.getAndIncrement() + "->" + s);
                }
            );

        }catch (IOException e) {
            e.printStackTrace();
        }

    }

}


你呢?
怎么

这是非常好的,因为
forEach
不会在并行流中强制执行遭遇顺序。如果您希望它强制执行遭遇顺序,请使用顺序流(或者使用
forEachOrdered
,以便您的意图显而易见)

如何

你呢


实际上,一个问题中有两个问题,第一个问题是它是否会在编写
stream.parallel().skip(1)
stream.skip(1.parallel()
时产生影响,第二个问题是其中一个或两个元素是否总是跳过第一个元素。另见

第一个答案是没有区别,因为指定
.sequential()
.parallel()
执行策略会影响整个流管道,当然,无论您将其放置在调用链的何处,除非您指定多个相互矛盾的策略,在这种情况下,最后一个策略获胜

因此,在任何一种情况下,您都在请求并行执行,这可能会影响
跳过
操作的结果,这是第二个问题的主题

答案并不是那么简单。如果流首先没有定义的相遇顺序,则可能会跳过任意元素,这是因为没有“first”元素,即使在源代码上迭代时可能会首先遇到元素

如果您有一个有序流,
skip(1)
应该跳过第一个元素,但这是最近才制定的。如中所述,链接无序终端操作会影响早期实现中的
跳过
操作,并且不确定这是否是有意的,如中所示,这恰好与您的代码相近;显然,跳过第一行是一种常见的情况

最后一句话是,早期JRE的行为是一个bug,在有序流上的
skip(1)
应该跳过第一个元素,即使流管道并行执行且终端操作无序。将jdk1.8.0_60命名为第一个固定版本,我可以对此进行验证。因此,如果在较旧的实现上使用,则在使用
.parallel()
和无序的
.forEach(…)
终端操作时,可能会遇到跳过不同元素的流。如果实现偶尔跳过预期的元素,这并不矛盾,这就是多线程的不可预测性


因此,答案仍然是
stream.parallel().skip(1)
stream.skip(1).parallel()
具有相同的行为,即使在早期版本中使用时也是如此,因为当与无序的终端操作(如
forEach
一起使用时,这两种行为同样不可预测。他们应该总是跳过具有有序流的第一个元素,当与
1.8.0_60
或更高版本一起使用时,他们应该跳过。您是否尝试过这两个元素来找出答案?您的问题的答案是肯定的。阅读“我尝试了第一个选项”,在我看来(实际上我非常确定)我没有跳过第一行/条目。我只是跳过了一些随机的条目。也许你是无意中发现的。检查您使用的是哪一个Java版本。@Andrew尝试这两个版本可能会证明它们是不同的,但确定它们是否必须相同是没有用的,这正是OP所要求的。他的意思不是“有时它可能会产生相同的结果”,而是“它必须产生相同的结果。”而尝试它并没有真正的帮助;您必须符合规格。谢谢,但我不太在乎性能。我在乎是跳过第一个条目还是某个随机条目。@peter.petrov这不是跳过一个随机条目。它仍然跳过相同的条目。你能提供一个问题的MCVE吗?是的,你的例子非常有限。这个问题是关于遭遇顺序的。怎么样
Stream.of("Hello", "How", "Are", "You?")
    .parallel()
    .skip(1)
    .forEach(System.out::println);
Stream.of("Hello", "How", "Are", "You?")
    .skip(1)
    .forEachOrdered(System.out::println);