Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I split a stream to handle elements in different ways?

I'm using code like this to process a file consisting of multiple lines:

BufferedReader reader = ...
reader.lines().forEach(Same common Action)

This works fine as long as every line needs to be handled the same way. But sometimes there may be several different actions.

For example, let's say the first line is a header and the other lines are content. For the first line I want to perform Action1, and for the others I want Action2.

In Java 7 style I'd do something like this:

String line;
boolean first = true;
while ( (line = reader.readLine()) != null) {
    if (first) {
        action1(line);
        first = false;
    } else {
        action2(line);
    }
}

But that's complex and ugly, and it is not using streams at all. How can I do that in an idiomatic way using Java 8 streams?

like image 823
Alstresh Avatar asked Nov 09 '17 11:11

Alstresh


3 Answers

Spliterator<String> sp = reader.lines().spliterator();    

sp.tryAdvance(YourConsumer)
sp.forEachRemaning(DifferentConsumer)
like image 75
Eugene Avatar answered Oct 26 '22 00:10

Eugene


Don’t make your life so hard:

String header = reader.readLine();
if(header != null) {
    action1(header);
    reader.lines().forEach(line -> action2(line));
}

or if you have already existing actions implementing Consumer<String>:

String header = reader.readLine();
if(header != null) {
    action1.accept(header);
    reader.lines().forEach(action2);
}
like image 37
Holger Avatar answered Oct 26 '22 00:10

Holger


You can try this with AtomicBoolean

AtomicBoolean first = new AtomicBoolean(true);
reader.lines()
      .forEach(s -> first.getAndSet(false) ? FirstConsumer : SecondConsumer);
like image 2
Yegor Babarykin Avatar answered Oct 26 '22 02:10

Yegor Babarykin