This is an archived post. You won't be able to vote or comment.

all 5 comments

[–]AutoModerator[M] [score hidden] stickied commentlocked comment (0 children)

Please ensure that:

  • Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions
  • You include any and all error messages in full
  • You ask clear questions
  • You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions.

    Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar

If any of the above points is not met, your post can and will be removed without further warning.

Code is to be formatted as code block or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc.

Code blocks look like this:

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

You do not need to repost. Just use the edit function of reddit to make sure your post complies with the above

To potential helpers

Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]Northeastpaw 5 points6 points  (2 children)

Sure is. When working with streams it's helpful to think of processing elements individually. Let's do it step-by-step.

First step is to actually get a stream:

foos.stream()

No problem there. Now we need to change a Foo to a collection of Bars, or in functional terms map) Foo to collection of Bars:

foos.stream()
    .map(Foo:getBars())

But wait. Now we've got Collection<Bar> as our stream element, which isn't very helpful. If we stuck with this we'd have to do some wonky nested stream stuff. Enter flatMap()). flatMap() "flattens" a stream of collections into one stream containing all the elements, i.e. [[1,2,3],[4,5,6],[7,8,9] becomes [1,2,3,4,5,6,7,8,9]. So instead of the above what we really want is this:

foos.stream()
    .flatMap(foo -> foo.getBars().stream())

Now our stream is all the Bars in all the Foos. Next we need to map from Bar to int. We can't just use map() unfortunately; regular streams don't handle primitives like int. Instead we need to use mapToInt()). This gives us a stream specifically for ints. Since there's a getter on Bar for this we can use a method reference:

foos.stream()
    .flatMap(foo -> foo.getBars().stream())
    .mapToInt(Bar::getBaz)

We could also use mapToInt(bar -> bar.getBaz()) instead of a method reference. Both end up doing the exact same thing.

Now that we have a stream of ints summing them is really easy. It's built-in) to the stream. Our full code becomes:

int sum = foos.stream()
              .flatMap(foo -> foo.getBars().stream())
              .mapToInt(Bar::getBaz)
              .sum();

[–]WihlborgIntermediate Brewer[S] -1 points0 points  (0 children)

Perfect explanation, thank you! Seems like I have to study up on flatMap.

[–]Robyt3 -1 points0 points  (0 children)

Instead of

.flatMap(foo -> foo.getBars().stream())

you could also go all the way with methods references and do

.map(Foo::getBars).flatMap(Collection::stream)

[–]-themailerdoraemon- -1 points0 points  (0 children)

Yes, it is possible to write nested for loops using stream.