• 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

why the need to use reduce in Java 8 ?

 
Ranch Hand
Posts: 1048
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I am starting to revise Java 8 and then I come across this code from https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps



but it can accomplish with the following :



I am terribly confusing....
 
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
But you can't use mapToInt() in the following scenario.By the way, read the documentation for reduce() and find out whywon't work correctly.
 
tangara goh
Ranch Hand
Posts: 1048
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I read the Oracle site but there is this part :
Or we could use a parallelizable collect form:


    ArrayList<String> strings = stream.collect(() -> new ArrayList<>(),
                                               (c, e) -> c.add(e.toString()),
                                               (c1, c2) -> c1.addAll(c2));


or, pulling the mapping operation out of the accumulator function, we could express it more succinctly as:


    List<String> strings = stream.map(Object::toString)
                                 .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

what is stream here ?
 
Campbell Ritchie
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You doubtless already know that there are usually multiple ways to do the same thing. The link you provided seems to say the same in Java22.
In the second code example (please use the code button) you are creating a Collector from its three parts. that makes it easier to run in parallel. The example you showed creates a List (actually, it is very specific about the exact sort of List wanted), and that is a starting point, calling the List's constructor.
The middle part tells you that whenever you encounter an element, it is to be added with the add() method.
When the separate parallel operations finish, the two Lists are put together and one collects all the results from the other with the addAll() method.
The variable stream is a notional variable meaning any sort of Stream, irrespective of how you created it. It is of course, a Stream<T>, and the compiler “knows” how to choose all the other generic type parameters for the rest of the Stream's progress.
 
tangara goh
Ranch Hand
Posts: 1048
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:
The variable stream is a notional variable meaning any sort of Stream, irrespective of how you created it. It is of course, a Stream<T>, and the compiler “knows” how to choose all the other generic type parameters for the rest of the Stream's progress.





I am not getting it,  So I tried out the example using the class Person.  it dosn't work out...as in it refuse to transform the Object to String and then collect the elements from the Person in the static list and make it into a new one...I am not comprehending the functions at all.

 
tangara goh
Ranch Hand
Posts: 1048
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please ignore the above.  I got it finally.  
List<Person> copy = persons.stream()
                .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

System.out.println("what we have now is " + List.of(copy));

Note: the oracle's site using map instead of stream() really stumbled me...or is there something I did not comprehend about that part that uses
 
Campbell Ritchie
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That would in your case take a Stream<Person> and map that person to a String (the name), and then create a new Stream<String>.
Find yourself a copy of Modern Java in Action by Urma Fusco and Mycroft (Manning, 2018) or one of its predecessors and read that. It is the best explanation of how Streams work that I can remember seeing.
 
Master Rancher
Posts: 5060
81
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

tangara goh wrote:Note: the oracle's site using map instead of stream() really stumbled me...or is there something I did not comprehend about that part that uses


They aren't using map instead of stream.  They are using a map on a stream.  You don't see the call to the stream() method in their example - instead, they use a variable named "stream" to indicate that they're dealing with something that's already a stream. In your example, you still need the stream() call to convert a List to a Stream.  Compare these two possibilities:

One gives you a List of Strings, while the other gives a List of Persons.  Which is correct will depend on what you need to do with this list - which do you need?

 
Mike Simmons
Master Rancher
Posts: 5060
81
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:But you can't use mapToInt() in the following scenario.


Interestingly though, this code masks a rather inefficient implementation, which is roughly equivalent to:

This is mostly OK... until we get to the

which is concatenating a String inside a loop.  This is probably fine for a small number of iterations - in this case, we have just four elements.  But it's O(n*n) performance overall, because every single time we go through the loop, we're building a new String by recopying everything in the previous string, plus one more word.  As the string length increases, the performance just gets worse and worse.  Instead, we'd be much better off with

Or

Of course, this effect could also be achieved more easily with

But that wasn't your point. ;)

Campbell Ritchie wrote:By the way, read the documentation for reduce() and find out whywon't work correctly.


Aside from the fact that String has no "-" operator defined?  I guess you meant using the Integer example from before, not the String version you just gave.
Staff note (Stephan van Hulst) :

I fixed it for you. The trick is to replace < and > symbols in your code with HTML entities.

 
Mike Simmons
Master Rancher
Posts: 5060
81
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I forget what the trick is to remove the < br /> nonsense - obviously, that wasn't in my original.
 
Author
Posts: 310
12
Scala IntelliJ IDE Netbeans IDE Python Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In case it's helpful to anyone looking at this later, the simple answer to the original title question "why the need to use reduce?" might reasonably be presented like this:

reduce (in it's various forms, along with collect which is a close relative) allows the creation of a single object as a "final answer" built from all the data in the stream. This is a sufficiently common requirement that a great many "special cases" are provided pre-built, including several, starting with sum(), that were discussed along the course of the thread.

IOW, if you can find a special case solution, use it. If your use case hasn't been coded up for you in a library, build it using reduce, or perhaps collect.

 
Campbell Ritchie
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:. . . Aside from the fact that String has no "-" operator defined?  I guess you meant using the Integer example from before . . .

Yes, I did.

Sorry, but I can't work out how to get rid of the <br/> tags.
 
PI day is 3.14 (march 14th) and is also einstein's birthday. And this is merely a tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic