累积Java流,然后才对其进行处理

我有一个类似于以下内容的文档:

data.txt中

100, "some text" 101, "more text" 102, "even more text" 

我使用正则表达式处理它并返回一个新的处理文档如下:

 Stream lines = Files.lines(Paths.get(data.txt); Pattern regex = Pattern.compile("([\\d{1,3}]),(.*)"); List result = lines.map(regex::matcher) .filter(Matcher::find) .map(m -> new MyClass(m.group(1), m.group(2)) //MyClass(int id, String text) .collect(Collectors.toList()); 

这将返回已处理的MyClass列表。 可以并行运行,一切正常。

问题是我现在有这个:

data2.txt

 101, "some text the text continues in the next line and maybe in the next" 102, "for a random number of lines" 103, "until the new pattern of new id comma appears" 

所以,我不知何故需要连接从流中读取的行,直到出现新的匹配。 (像缓冲区?)

我试图收集字符串,然后收集MyClass(),但没有成功,因为我实际上无法拆分流。

Reduce会让人联想到连接行,但我会连接只是行,我不能减少并生成一个新的行流。

任何想法如何用java 8流解决这个问题?

这是java.util.Scanner的工作。 随着即将推出的Java 9,你会写:

 List result; try(Scanner s=new Scanner(Paths.get("data.txt"))) { result = s.findAll("(\\d{1,3}),\\s*\"([^\"]*)\"") //MyClass(int id, String text) .map(m -> new MyClass(Integer.parseInt(m.group(1)), m.group(2))) .collect(Collectors.toList()); } result.forEach(System.out::println); 

但是由于在Java 8下不存在生成findAllStream ,我们需要一个帮助方法:

 private static Stream matches(Scanner s, String pattern) { Pattern compiled=Pattern.compile(pattern); return StreamSupport.stream( new Spliterators.AbstractSpliterator(1000, Spliterator.ORDERED|Spliterator.NONNULL) { @Override public boolean tryAdvance(Consumer action) { if(s.findWithinHorizon(compiled, 0)==null) return false; action.accept(s.match()); return true; } }, false); } 

用这个帮助方法替换findAll ,我们得到了

 List result; try(Scanner s=new Scanner(Paths.get("data.txt"))) { result = matches(s, "(\\d{1,3}),\\s*\"([^\"]*)\"") // MyClass(int id, String text) .map(m -> new MyClass(Integer.parseInt(m.group(1)), m.group(2))) .collect(Collectors.toList()); }