I have the following file format:
Text1
+ continuation of Text1
+ more continuation of Text1
Text2
+ continuation of Text2
+ more continuation of Text2
+ ev
Assuming that you run this sequentially only and really want to use streams:
List<String> result = Files.lines(Paths.get("YourPath"))
.collect(() -> new ArrayList<>(), (list, line) -> {
int listSize = list.size();
if (line.startsWith("+ ")) {
list.set(listSize - 1, list.get(listSize - 1) + line.substring(2));
} else {
list.add(line);
}
}, (left, right) -> {
throw new RuntimeException("Not for parallel processing");
});
In Java 9, you could use
static final Pattern LINE_WITH_CONTINUATION = Pattern.compile("(\\V|\\R\\+)+");
…
try(Scanner s = new Scanner(file)) {
s.findAll(LINE_WITH_CONTINUATION)
.map(m -> m.group().replaceAll("\\R\\+", ""))
.forEach(System.out::println);
}
Since Java 8 lacks the Scanner.findAll(Pattern) method, you may add a custom implementation of the operation as a work-around
public static Stream<MatchResult> findAll(Scanner s, Pattern pattern) {
return StreamSupport.stream(new Spliterators.AbstractSpliterator<MatchResult>(
1000, Spliterator.ORDERED|Spliterator.NONNULL) {
public boolean tryAdvance(Consumer<? super MatchResult> action) {
if(s.findWithinHorizon(pattern, 0)!=null) {
action.accept(s.match());
return true;
}
else return false;
}
}, false);
}
which can be used like
try(Scanner s = new Scanner(file)) {
findAll(s, LINE_WITH_CONTINUATION)
.map(m -> m.group().replaceAll("\\R\\+", ""))
.forEach(System.out::println);
}
which will make the future migration easy.