一尘不染

这是Files.lines()中的错误,还是我对并行流有误解?

java

环境:Ubuntu x86_64(14.10),Oracle JDK 1.8u25

我尝试使用的并行流,Files.lines()但我想要.skip()第一行(这是带有标头的CSV文件)。因此,我尝试这样做:

try (
    final Stream<String> stream = Files.lines(thePath, StandardCharsets.UTF_8)
        .skip(1L).parallel();
) {
    // etc
}

但是随后一列无法解析为一个整数…

所以我尝试了一些简单的代码。文件问题很简单:

$ cat info.csv 
startDate;treeDepth;nrMatchers;nrLines;nrChars;nrCodePoints;nrNodes
1422758875023;34;54;151;4375;4375;27486
$

代码也同样简单:

public static void main(final String... args)
{
    final Path path = Paths.get("/home/fge/tmp/dd/info.csv");
    Files.lines(path, StandardCharsets.UTF_8).skip(1L).parallel()
        .forEach(System.out::println);
}

系统地 得到了以下结果(好的,我只运行了大约20次):

startDate;treeDepth;nrMatchers;nrLines;nrChars;nrCodePoints;nrNodes

我在这里想念什么?


编辑 似乎问题或误解根源远不止于此(以下两个示例是由FreeNode的## java的同伴编写的):

public static void main(final String... args)
{
    new BufferedReader(new StringReader("Hello\nWorld")).lines()
        .skip(1L).parallel()
        .forEach(System.out::println);

    final Iterator<String> iter
        = Arrays.asList("Hello", "World").iterator();
    final Spliterator<String> spliterator
        = Spliterators.spliteratorUnknownSize(iter, Spliterator.ORDERED);
    final Stream<String> s
        = StreamSupport.stream(spliterator, true);

    s.skip(1L).forEach(System.out::println);
}

打印:

Hello
Hello

@Holger认为发生这种情况对于其是任何流ORDERED,而不是SIZED与该其他样本:

Stream.of("Hello", "World")
    .filter(x -> true)
    .parallel()
    .skip(1L)
    .forEach(System.out::println);

同样,它源于已经进行的所有讨论,即问题是否存在.forEach()


阅读 772

收藏
2020-09-08

共1个答案

一尘不染

由于问题的当前状态与此处先前的陈述完全相反,因此应注意,BrianGoetz现在有明确声明,将无序特征反向传播到skip操作之后被视为错误。还指出,现在认为它根本不对终端操作的有序性进行反向传播。

还有一个相关的错误报告JDK-8129120,其状态为“已在Java
9中修复”,并且已反向移植到Java
8,更新为60

我进行了一些测试,jdk1.8.0_60看来现在的实现确实表现出了更直观的行为。

2020-09-08