简体   繁体   中英

Java8 - Count after filter on stream

I hope this question was not asked before. In java 8, I have an array of String myArray in input and an integer maxLength . I want to count the number of string in my array smaller than maxLength. I WANT to use stream to resolve this issue.

For that I thought to do this :

int solution = Arrays.stream(myArray).filter(s -> s.length() <= maxLength).count();

However I'm not sure if it is the right way to do this. It will need to go through first array once and then go through the filtered array to count.

But if I don't use a stream, I could easely make an algorithm where I loop once over myArray.

My questions are very easy: Is there a way to resolve this issue with the same time performance than with a loop ? Is it always a "good" solution to use stream ?

However I'm not sure if it is the right way to do this. It will need to go through first array once and then go through the filtered array to count.

Your assumption that it will perform multiple passes is wrong. There is something calling operation fusion ie multiple operations can be executed in a single pass on the data;

In this case Arrays.stream(myArray) will create a stream object (cheap operation and lightweight object) , filter(s -> s.length() <= maxLength).count(); will be combined into a single pass on the data because there is no stateful operation in the pipeline as opposed to filtering all the elements of the stream and then counting all the elements which pass the predicate.

A quote from Brian Goetz post here states:

Stream pipelines, in contrast, fuse their operations into as few passes on the data as possible, often a single pass. (Stateful intermediate operations, such as sorting, can introduce barrier points that necessitate multipass execution.)

As for:

My questions are very easy: Is there a way to resolve this issue with the same time performance than with a loop ?

depends on the amount of data and cost per element. Anyhow, for a small number of elements the imperative for loops will almost always win if not always.

Is it always a "good" solution to use stream ?

No, if you really care about performance then measure , measure and measure .

Use streams for it being declarative, for its abstraction, composition and the possibility of benefitting from parallelism when you know you will benefit from it that is .

You can use range instead of stream and filter the output.

int solution = IntStream.range(0, myArray.length)
                .filter(index -> myArray[index].length() <= maxLength)
                .count();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM