在Java中创建一个流,其中包含另一个映射中作为值的映射中的值。

4

对于标题不太清晰的问题,我感到抱歉。如果您有更好的标题,请告诉我,我可以更改。

我有两种类型的对象,书签和修订。我有一个大型地图,如下所示:

Map<Long, Bookmark> mapOfBookmarks;

它包含键值对,格式如下:

key: value

1L: Bookmark1,
2L: Bookmark2,
...

每个书签都有一个“getRevisions()”方法,它返回一个Map。
public Map<Long, Revision> getRevisions();

我想创建一个包含mapOfBookmarks下所有修订版本的流。本质上,我想做到这一点:

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

然而,我希望能够使用Stream的功能来完成它,更像:

return mapOfBookmarks.values().stream().everythingElseThatIsNeeded();

这基本上就像是说:

return Stream.of(revision1, revision2, revision3, revision4, ...);

我该怎么写呢?需要注意的是,它正在循环遍历的数据集可能非常庞大,因此列表方法并不是一个好的选择。

我正在使用Windows 7和Java 8。

2个回答

4
一个你可能需要的是flatmap。当你需要展开嵌套流时,flatmap就是答案。
List<Revision> all =
    mapOfBookmarks.values().stream()
        .flatMap(c -> c.getRevisions().values().stream())
        .collect(Collectors.toList());

3
您正在寻找 flatMap(mapper) 操作:

返回一个流,其中包含用提供的映射函数对每个元素应用所产生的映射流的内容替换该流中每个元素的结果。

在这种情况下,我们通过调用 stream() 创建了一个 Stream<Bookmark>,将其扁平化为每个书签的修订版本,最后使用 toList() 将其收集到列表中。
List<Revision> revisions = 
    mapOfBookmarks.values()
                  .stream()
                  .flatMap(bookmark -> boormark.getRevisions().values().stream())
                  .collect(Collectors.toList());

请注意,您当前的代码也可以通过调用 addAll 来改进,而不是循环处理每个修订版本:
for (Bookmark bookmark : mapOfBookmarks.values()) { // loop through each bookmark in the map of bookmarks ( Map<Long, Bookmark> )
    revisions.addAll(bookmark.getRevisions().values());
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接