环境: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
}
但随后一列未能解析为 int...
所以我尝试了一些简单的代码。该文件的问题很简单:
$ 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()
(如 @SotiriosDelimanolis first pointed out )有关。
最佳答案
由于问题的当前状态与此处先前的陈述完全相反,因此应该注意,现在有一个 explicit statement by Brian Goetz关于通过 skip
操作的无序特征的反向传播被认为是一个错误。 It’s also stated现在认为它根本没有终端操作的有序性的反向传播。
还有一个related bug report, JDK-8129120其状态为“已在 Java 9 中修复”,它是 backported to Java 8, update 60
我用 jdk1.8.0_60
做了一些测试,看起来现在的实现确实表现出更直观的行为。
关于java - 这是 Files.lines() 中的错误,还是我对并行流有误解?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28259636/