Sorry about the title of the question; it was kind of hard for me to make sense of it. If you guys have a better title, let me know and I can change it.
I have two types of objects, Bookmark and Revision. I have one large Map, like so:
Map<Long, Bookmark> mapOfBookmarks;
it contains key: value pairs like so:
1L: Bookmark1,
2L: Bookmark2,
...
Each Bookmark has a 'getRevisions()' method that returns a Map
public Map<Long, Revision> getRevisions();
I want to create a Stream that contains all revisions that exist under mapOfBookmarks. Essentially I want to do this:
List<Revision> revisions = new ArrayList<>();
for (Bookmark bookmark : mapOfBookmarks.values()) { // loop through each bookmark in the map of bookmarks ( Map<Long, Bookmark> )
for (Revision revision : bookmark.getRevisions().values()) { // loop through each revision in the map of revisions ( Map<Long, Revision> )
revisions.add(revision); // add each revision of each map to the revisions list
}
}
return revisions.stream(); // return a stream of revisions
However, I'd like to do it using the functionality of Stream, so more like:
return mapOfBookmarks.values().stream().everythingElseThatIsNeeded();
Which would essentially be like saying:
return Stream.of(revision1, revision2, revision3, revision4, ...);
How would I write that out? Something to note is that the dataset that it is looping through can be huge, making the list method a poor approach.
I'm using Windows 7 and Java 8
A flatmap
is what you looking for. When you have streams contained within a stream that you wish to flatten, then flatmap
is the answer,
List<Revision> all =
mapOfBookmarks.values().stream()
.flatMap(c -> c.getRevisions().values().stream())
.collect(Collectors.toList());
You are looking for the flatMap(mapper)
operation:
Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.
In this case, we're making a Stream<Bookmark>
by calling stream()
, flat mapping it to the revisions of each bookmark and, finally, collecting that into a list with toList()
.
List<Revision> revisions =
mapOfBookmarks.values()
.stream()
.flatMap(bookmark -> boormark.getRevisions().values().stream())
.collect(Collectors.toList());
Note that your current code could also be improved by calling addAll
instead of looping over each revisions:
for (Bookmark bookmark : mapOfBookmarks.values()) { // loop through each bookmark in the map of bookmarks ( Map<Long, Bookmark> )
revisions.addAll(bookmark.getRevisions().values());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With