Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 streams conditional processing

I'm interested in separating a stream into two or more substreams, and processing the elements in different ways. For example, a (large) text file might contain lines of type A and lines of type B, in which case I'd like to do something like:

File.lines(path) .filter(line -> isTypeA(line)) .forEachTrue(line -> processTypeA(line)) .forEachFalse(line -> processTypeB(line)) 

The previous is my attempt at abstracting the situation. In reality I have a very large text file where each line is testing against a regex; if the line passes, then it is processed, whereas if it is rejected, then I want to update a counter. This further processing on rejected strings is why I don't simply use filter.

Is there any reasonable way to do this with streams, or will I have to fallback to loops? (I would like this to run in parallel as well, so streams are my first choice).

like image 611
gdiazc Avatar asked Mar 07 '16 21:03

gdiazc


People also ask

Does Java 8 support streams?

Java 8 offers the possibility to create streams out of three primitive types: int, long and double. As Stream<T> is a generic interface, and there is no way to use primitives as a type parameter with generics, three new special interfaces were created: IntStream, LongStream, DoubleStream.

How do I add an IF condition in stream API?

Java 8 Streams If Else condition In forEach() In java 8, stream api is added with the forEach() method and inside this, we can add the if-else conditions. But, forEach() is called on the streams.

How do you handle if-else in stream?

Conventional if/else Logic Within forEach() First of all, let's create an Integer List and then use conventional if/else logic within the Integer stream forEach() method: List<Integer> ints = Arrays. asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); ints. stream() .


1 Answers

Java 8 streams weren't designed to support this kind of operation. From the jdk:

A stream should be operated on (invoking an intermediate or terminal stream operation) only once. This rules out, for example, "forked" streams, where the same source feeds two or more pipelines, or multiple traversals of the same stream.

If you can store it in memory you can use Collectors.partitioningBy if you have just two types and go by with a Map<Boolean, List>. Otherwise use Collectors.groupingBy.

like image 120
Cosu Avatar answered Oct 13 '22 03:10

Cosu