Well, well. It seems I post faster that I thought regarding the additional Stream API functionalities. Soon after I published the stream how-to, a friend of mine came and gave me a feedback, or request precisely, about the functionalities which I did not discuss. Also, he thought my post was like an unfinished business. So Roberto, this one for fulfilling your special request :).
Whenever you are doing computational process through a collection, sometimes you need to know whether it contains specific object or not. Or maybe you want to acknowledge whether a collection contains all objects you need or not. Stream API comes with three match functions for these needs. Those are
noneMatch. Here are the samples:
In other cases, maybe you have a stream which contains many collections. And you want to access those collections with a single operation. For this purpose, you can use the
flatMap operation. It basically transforms each element in stream into another stream objects.
For instance, I have two lists. The first one contains positive numbers and the other one contains negative numbers. My purpose is to get the odd numbers from both lists within one single stream operation.
When you are working with a set of data, occasionally you need to accumulate them into one single value. Such operations, like
max, which return number. But, what about if we want to get total sum of all numbers in the stream? Or String operation? To answer these questions, Stream API offers reduce operation to facilitate our needs.
Reduce operation itself has three types. The first one is the simplest one. It only accepts
BinaryOperator as an accumulator function. Put your logic to combine the stream into single operation under this function. For example, I want to display all Car models into one single line with separator |. Note: I still use the list of Cars example from previous post.
The second one is reduce method with two parameters. The identity value and
BinaryOperator accumulator. The accumulator will use the identity value for first accumulation process. I said first because we don’t use
parallelStream yet. The next sample is more or less similar with the previous one, but the different is I want to have Renault in the beginning of my result.
I already mentioned a little bit about
parallelStream in the previous paragraph. Now, we can try to use
parallelStream into our second reduce sample.
Errr… the result is not what I expected. I have four Renaults! (Wow.. I must be rich). So what is going on here?
Stream API has another type of streams, which is a parallel one. Parallel stream offers faster execution if you are processing huge number of data. But be careful with its overhead, just like the four Renaults sample.
In order to handle the parallel stream problem with reduce operation, we need another and the last type of reduce. It offers three parameters: initial value, BiFunction as an accumulator and BinaryOperator as a combiner. Now we have to remove the rest of three Renaults using this last reduce type.
Should we go parallel instead of sequential stream? My opinion, it is better to use sequential stream as much as you can, unless you have a performance problem. Because you need additional logic to handle the multiple processes. But, I open to any discussion about this preferences.
Once the terminal operation is executed, stream is closed and cannot be reused. It will throw
IllegalStateException whenever you try to call after the stream is closed.
However, we have a workaround for this problem. Either you create another stream instance, or more elegant way, using
So, that’s all of my promise to post the rest of Stream API operations. I hope it will help you to know more about stream features. Happy coding then!