Win a copy of OCP Oracle Certified Professional Java SE 11 Developer Practice Tests this week in the OCP 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
  • Paul Clapham
  • Jeanne Boyarsky
  • Ron McLeod
  • Tim Cooke
Sheriffs:
  • Devaka Cooray
  • paul wheaton
  • Mark Herschberg
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Frits Walraven
  • Jj Roberts
Bartenders:
  • Carey Brown
  • salvin francis
  • Piet Souris

Turning nested foreach loops into streams

 
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello! I have some problems with some foreach loops in my code. My teacher wants me to reduce all my foreach loops to streams. I managed to make most of them into streams but there are still some, that just dont work out as a stream for me.



There is one of them that I cant figure out, how to turn it into a stream. I'd appreciate your help
 
Saloon Keeper
Posts: 323
42
Firefox Browser MySQL Database Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It looks like you have a list of lists and you are trying to iterate through every item of every list. You could do that by combining the lists to make a single list of all items, and then iterate over that. We can do something similar with the stream method FlatMap. The FlatMap methods takes multiple streams and merges them into one, which you can process.

A very contrived example:Assuming a Student class

Can you apply that to your case?

Edit: Thanks Ron for pointing out that I used == for testing String equality. equals() should always be used to compare String values.
 
Matthias Utrata
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am not sure, if that is the case. I can leave a pastebin link in here though, if that helps you.

https://pastebin.com/1dWCk8V4
 
Jj Roberts
Saloon Keeper
Posts: 323
42
Firefox Browser MySQL Database Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So the idea is to stream your list of PickOrder objects, and then FlatMap the lists of PickOrderLine objects that they contain, to get a stream of PickOrderLine. After that, you can find what you need from that. Can you do that?
 
Matthias Utrata
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I tried to start it off with that, but I cannot use pickOrderLine in the filer method
 
Jj Roberts
Saloon Keeper
Posts: 323
42
Firefox Browser MySQL Database Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You will need to stream the list: What issues are you experiencing with your filter()? Can you show what you are trying, and why it didn't work?
 
Matthias Utrata
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Is that the correct way? I tried to add a return on the start, because there is a return statement in the if statement, though when I add the return at the start. The whole stream has red waves. Is there a way to use the return with the stream?
 
Marshal
Posts: 72036
312
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is good to see teachers who aren't scared to teach Streams code

Please post the relevant code here; many people are reluctant to open PasteBin and similar links.

Please explain very simply what the two loops are supposed to do. It may be easier to work out the Streams from scratch than to try ro convert loops to Streams.
 
Matthias Utrata
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Campbell Ritchie

My code is at the very start of this thread. That is the code I need to turn into a stream somehow. It is the only piece of code I have along with some other methods, which include also foreach loops, that need to be turned into streams.
 
Jj Roberts
Saloon Keeper
Posts: 323
42
Firefox Browser MySQL Database Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Matthias Utrata wrote:Is that the correct way? I tried to add a return on the start, because there is a return statement in the if statement, though when I add the return at the start. The whole stream has red waves. Is there a way to use the return with the stream?

Your IDE will tell you what is wrong; try hovering over the red lines. At the end of your stream code you still have a Stream<PickOrderLine>, just minus the items that were rejected by your filter. You still need to get the PickOrderLine object you want from the stream, and then use it to get a Product object to return.
 
Matthias Utrata
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jj Roberts wrote:

Matthias Utrata wrote:Is that the correct way? I tried to add a return on the start, because there is a return statement in the if statement, though when I add the return at the start. The whole stream has red waves. Is there a way to use the return with the stream?

Your IDE will tell you what is wrong; try hovering over the red lines. At the end of your stream code you still have a Stream<PickOrderLine>, just minus the items that were rejected by your filter. You still need to get the PickOrderLine object you want from the stream, and then use it to get a Product object to return.



And how? I am not allowed to use loops for it.
 
Jj Roberts
Saloon Keeper
Posts: 323
42
Firefox Browser MySQL Database Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So at this point you have a stream of one or more PickOrderLine objects which matched your filter. Now you want to get the product code of one of them, so that you can use that product code to get the right Product from your list, right? If you have a look in the Oracle's documentation for Stream you will find how to get items from a stream. In particular, have a look at the findXXX() methods. If you need to, do some research on things that come up.
 
Sheriff
Posts: 22080
113
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In addition to what JJ said, the findXXX methods don't return a PickOrderLine because these methods take into account the possibility that there is no match. The returned object has methods to get a PickOrderLine, but it forces you to think about what to do if there is no match. Do you return null or a default value? Do you throw an exception? It's all up to you!

One hint: don't use .get() as it may throw some generic exception and you may not even be aware. Use .orElseThrow() to get the same generic exception, or the other .orElseThrow to have control over the thrown exception. Even though .get() and .orElseThrow() do the same, the second is preferred because it shows you are aware of the possible exception and are willing to accept it.


One more piece of advice - split stream code so each operation has its own line:

This has at least two advantages:
* If you add a breakpoint on the filter line, IDEs will hit that breakpoint not just when filter is called, but also each time the lambda inside it is called.
* If an exception occurs, the correct line number is reported.

The second is reason alone to do this split. In your code, if that line triggers a NullPointerExeption, where is it? Is it pickOrders? Is it in the flatMap operation? In the filter operation? You can't easily tell because they are all on the same line. In my example it's easier to see where it occurs because each will have its own line number.
 
Matthias Utrata
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I tried it with the findFirst Method, but that gives me an optional if I return it and not a product
 
Saloon Keeper
Posts: 12715
277
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You get an Optional because the stream might not contain any elements for you to find one from. This happens if pickOrders is empty, if none of the pickOrders have any pickOrderLines, or if none of the pickOrderLines has a quantity that is high enough. Rob Spoor already warned about this.

Again, what do you want to do when there is no PickOrderLine that matches your criteria?
 
Matthias Utrata
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have no idea. I just need to turn my for each loops into one stream
 
Rob Spoor
Sheriff
Posts: 22080
113
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So what does your original code return if it doesn't find a match? And how can you make the Optional return that? In other words, which method of Optional will either return a matching PickOrderLine, or else return null?
 
Matthias Utrata
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I can only really say, that this method uses the getNextProduct Method
 
Campbell Ritchie
Marshal
Posts: 72036
312
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That looks very complicated. Avoid if‑else with /streams if you can. You can limit the size of a Stream with, would you believe, its limit(long) method. Why are you sorting something before running the Stream? Why not leave the original source unchanged (that is somethng you should always do with Streams anyway) and see whether there are any Stream methods that will sort anything..
 
Bartender
Posts: 7730
70
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1) Can you wrap your very long lines so we don't have to scroll left-right?

2) Can you add a class around the method with a main() and hard code some dummy data to test your method with a known, expected outcome? Preferably, something we could copy and run on our own machines (SSCCE).
 
Matthias Utrata
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I sadly cannot to the second part, because I would need to post my whole stuff in here and that contains out of 10 classes
 
Campbell Ritchie
Marshal
Posts: 72036
312
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No, you wouldn't; you would have to psot a simplified version representing an SSCCE.

Please don't quote the whole of the preceding post.
 
Matthias Utrata
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I do not know how to simplify it. It is so much to go through
 
Carey Brown
Bartender
Posts: 7730
70
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's a hack at it. Hadn't gotten to PickOrder though. Got rid of Location. Simplified Product to a String.
 
I guess I've been abducted by space aliens. So unprofessional. They tried to probe me with this tiny ad:
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic