Win a copy of Testing JavaScript Applications this week in the HTML Pages with CSS and JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Liutauras Vilda
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • fred rosenberger
  • salvin francis
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Carey Brown

Java streams - when to NOT use java streams ?

 
Ranch Hand
Posts: 143
5
IntelliJ IDE Eclipse IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have learned a bit about streams & I am eager to use them as much as possible. I don't use streams when it seems more complicated than a simple for loop, which has rarely happened so far. In the following example, I feel that a for loop looks better, i.e is short and easier to understand.

I wonder if there is a comprehensive set of examples or guidelines for when to use and when to not use streams. Here are 3 examples, but could there be more ?


 
Marshal
Posts: 69847
278
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Addition} Added discussion to our streams forum.


I am not convinced that link provides either guidelines nor good examples. You have one example producing a multiplication table, and that shows that nested streams are no less awkward than nested loops. You have an example to produce letters from A to Z to AA and ZZ, and that has an incomprehensible algorithm. You have examples about performances showing only a slight difference. [Remember he said the second, larger difference wasn't reproducible.]
Your example is semantically incorrect; the two lines 12 and 15 are semantically different, which is why you have the clear() call in line 13. Line 12 should use Collectors.toList(), not Collectors.toCollection(ArrayList::new). Line 12 is a declaration and initialisation and 15 is a for statement. There are two reasons why line 12 appears more complex:-
  • 1: It is doing more than line 15
  • 2: It is more self‑contained; line 12 can confine the List to a narrower scope than 15.
  • If you formatted the code correctly, you would probably find that the loop is longer and no more legible than the Stream.I agree that sometimes people find stream code harder to rread. But that really means that these people haven't become familiar with stream code. As you suggest, it is a new skill, and it takes time and effort to learn a new skill.
     
    Bartender
    Posts: 4006
    156
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:I agree that sometimes people find stream code harder to rread. But that really means that these people haven't become familiar with stream code. As you suggest, it is a new skill, and it takes time and effort to learn a new skill.


    One life (eh, type) saver is to do a static import of Collectors.
     
    Sheriff
    Posts: 15801
    264
    Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:If you formatted the code correctly... the loop is longer and no more legible than the Stream.


    A couple of things that you can do to streamline that a little bit more:
    1. static import Collectors.toList (Edit: I see Piet already pointed this out)
    2. Choose good names (which you have for the most part but mapper could be better)

     
    Junilu Lacar
    Sheriff
    Posts: 15801
    264
    Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:sometimes people find stream code harder to rread. But that really means that these people haven't become familiar with stream code. As you suggest, it is a new skill, and it takes time and effort to learn a new skill.


    And it also takes a while for people to learn how to think differently. With streams, think more functional (focus more on intent) vs. imperative (focus more on implementation). You also need to have a wide familiarity so you can pick the most appropriate tool that will make the intent really obvious and the operation precise. When stream code is obfuscated, it's usually because the person writing it was focused more on the mechanics rather than the intent and/or a sledgehammer was used instead of scalpel.

    Note the stark difference in clarity of the version that Campbell gave vs. line 12 of the original example. But then again to the earlier point, "clarity" is in the eye of the beholder and in this case you have to at least understand what you're looking at to see it for what it is.
     
    Tom Joe
    Ranch Hand
    Posts: 143
    5
    IntelliJ IDE Eclipse IDE Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:[Addition} Added discussion to....Line 12 should use Collectors.toList(), not Collectors.toCollection(ArrayList::new)....learn a new skill.



    The book (core java for the impatient) asks to return an ArrayList instead of the generic List. I wonder what we gain by doing that in a book example like this. That is why I used toCollection(...) instead of toList(...).
     
    Tom Joe
    Ranch Hand
    Posts: 143
    5
    IntelliJ IDE Eclipse IDE Java
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Piet Souris wrote:One life (eh, type) saver is to do a static import of Collectors.



    As a beginner to streams, I'd like to avoid using static imports & allowing an IDE to auto complete stream code for me. This is so that I can remember the streams syntax and functionality.
     
    Campbell Ritchie
    Marshal
    Posts: 69847
    278
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Tom Joe wrote:. . . The book . . . asks to return an ArrayList . . .

    Please supply more details including page number; I might have that book. But I probably shan't look at it till tomorrow. Maybe it was demonstrating how to create a specific type of List,

    Although I like Horstmann's books, they are not intended for beginners. Consider anotheer book; my faourite for introducing Streams is Urma Fusco and Mycroft Modern Java in Action (Manning: older editions have different names).
     
    Piet Souris
    Bartender
    Posts: 4006
    156
    • Likes 2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Tom wrote:


    You can use: var results = ..., since the correct type will be inferred.

    What confused me a couple of days ago was that with:

    you can also use:

    one of those (rare/many) moments that you think you don't understand Java anymore...    
     
    Campbell Ritchie
    Marshal
    Posts: 69847
    278
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    It just goes to show you there are several different ways to do anything.
     
    Sheriff
    Posts: 21972
    106
    Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Piet Souris wrote:you can also use:

    one of those (rare/many) moments that you think you don't understand Java anymore...    


    Which is nothing more than a Function wrapped in a Function (through a method reference). It's the same as t -> mapper.apply(t).
     
    Junilu Lacar
    Sheriff
    Posts: 15801
    264
    Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Tom Joe wrote:

    Campbell Ritchie wrote:[Addition} Added discussion to....Line 12 should use Collectors.toList(), not Collectors.toCollection(ArrayList::new)....learn a new skill.



    The book (core java for the impatient) asks to return an ArrayList instead of the generic List. I wonder what we gain by doing that in a book example like this.


    Probably to force the use of ArrayList::new instead of Collectors.toList(). Book examples are usually meant to highlight a concept so unless the concept is about coding in the real world, don't assume examples are good for use in the real world.

    On the other hand, real-world code that uses ArrayList::new instead of Collectors.toList() could indicate that the choice of using an ArrayList is intentional and/or significant somehow whereas using Collectors.toList() would tell me that we're dealing purely with intent and don't care about the implementation. Prefer the latter but make sure you can easily understand the reasons behind the former.
     
    And inside of my fortune cookie was this tiny ad:
    Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
    https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
      Bookmark Topic Watch Topic
    • New Topic