Java 8 streams when and why

Viewed 399

I recently started working on a project where they encourage writing code with streams lambdas and such. Basically, the functional programming approach. While I find streams appealing, I have a few doubts about them. They are as follows.

  1. Performance - are serial streams really faster and more scalable than corresponding collections? Or are streams only preferable because someday we might use the stream().parallel() version?

  2. Memory usage - are streams a burden on the heap memory given that the terminal operations like collect(toList()) usually create a new object?

  3. Garbage collection (GC) - are streams more GC friendly than collections?

  4. Programming paradigm - I personally think mixing the functional programming style with OOPs is kind of gonna result in issues.

  5. Debugging - I personally debug my code by pen and paper rather than using a debugger (which some people might prefer). How good are streams when it comes to debugging?

  6. Operations Complexity - when it comes to writing everyday code (filtering grouping collecting mapping) streams are a cakewalk, but I find that when I have to write complex logic I end up resorting to the old collection based approach as it is more tweakable. Am I the only one doing this?

I understand that I am asking multiple questions here, but really they are 6 parts of the same question mentioned in the title. Hope for at least a summary like answer to each of these sub-questions. It'd be helpful if someone also could add a link to dive deep into all of these.

cheers!!

2 Answers

Performance - are serial streams really faster and more scalable than corresponding collections?

No. At least, not on average ... with current Stream implementations.

Or are streams only preferable because someday we might use the stream().parallel() version?

Possibly yes. However, for many use-cases, the overheads of using parallel() outweigh the possible speedup.

Memory usage - are streams a burden on the heap memory given that the terminal operations like collect(toList()) usually create a new object?

AFAIK, No. There is typically no reduction in memory usage.

Garbage collection (GC) - are streams more GC friendly than collections?

AFAIK, No.

Programming paradigm - I personally think mixing the functional programming style with OOPs is kind of gonna result in issues.

That is your opinion.

If you stick with making your stream operations side-effect free, there shouldn't be any issues.

  • The documentation recommends against side-effects in stream operations.
  • If you rely on side-effects, that's not functional.

Debugging - I personally debug my code by pen and paper rather than using a debugger (which some people might prefer). How good are streams when it comes to debugging?

That's a matter of opinion. I personally think that it makes no difference to debugging.

Operations Complexity - when it comes to writing everyday code (filtering grouping collecting mapping) streams are a cakewalk, but I find that when I have to write complex logic I end up resorting to the old collection based approach as it is more tweakable. Am I the only one doing this?

You are not the only one. On the other a lot of people do a lot more complicated things using than simple filtering, grouping, collecting and mapping. The more you use streams, the better you will get at spotting other use-cases. But the flip-side is that some people seem to want to do things with streams that they probably shouldn't.


I recently started working on a project where they encourage writing code with streams lambdas and such.

That's between you and the rest of the team. I don't think it is my / our business to get into your project team's debates on this.

One of the main benefits to Java streams is that they will process data in real-time. For example, let's say you have an array 1000 data points. If you were to process this with a traditional method, it would require batch processing. This means that you wouldn't get the results for the first processed item until all items have processed. As you can imagine, this can slow things down quite a bit, especially when your method is part of a pipeline. Say it takes this method 10 minutes (extreme example to prove a point) to complete. Also, imagine that this is the first of 20 different processes, each taking about the same amount of time. You're looking at two hundred minutes to process an array.

Now imagine that same pipeline, all of the processes taking the same amount of time, but instead of batch processing you are streaming the data through. This involves processing array items one by one through a function. The consequence is that as soon as your first item is done, it can go on to the next point in the process. In our example, the first item would likely finish in a couple seconds. Instead of waiting for 999 other pieces of data to process , it can immediately move to the next Link in the chain . This ensures that the processes at the back end of the chain are blocked for a much smaller length of time.

Obviously, this is a theoretical example. As such, it doesn't take concerns such as thread blocking into account. However, the advantages being able to run multiple processes on a collection concurrently are still huge.

This is also why most functions for Java streams will return a stream. They were designed to be run in a sort of pipeline

Related