java - Java 8 Stream API:如何将列表转换为地图列表中有重复的键?
问题描述
我有一个包含以下字段的类:
public class Item{
private String name;
private Long category;
private Set<Long> containers;
}
我需要做的是转
List<Item> items
成一个
Map<Long/*categoryID*/, Set<Long/*Containers*/>>
使用 Java 8 流 API。
现在我可以使用Itarable
and some得到相同的结果if
,如下所示:
List<Item> items = getItems();
Iterator<Item> itemsIterator = items.iterator();
Map<Long/*categoryID*/, Set<Long/*Containers.ID*/>> containersByCategoryMap = new HashMap<>();
while (itemsIterator.hasNext()) {
Item item = itemsIterator.next();
Long category = item.getCategory();
Set<Long> containers = item.getContainers();
if (containersByCategoryMap.containsKey(category)) {
Set<Container> containersByCategory = containersByCategoryMap.get(category);
containersByCategory.addAll(containers);
} else {
Set<Container> containersByCategory = new HashSet<>(containers);
containersByCategoryMap.put(category, containersByCategory);
}
}
如何使用 Stream API 获得相同的结果?
我尝试过这样的事情,但显然我得到了重复键异常,因为每个类别都有多个项目......
containersByCategoryMap = items.stream().collect(Collectors.toMap(item -> item.getCategory(), item -> item.getContainers()));
解决方案
由于 java-9 有Collectors.flatMapping
:
Map<Long, Set<Long>> map = items.stream()
.collect(Collectors.groupingBy(
Item::getCategory,
Collectors.flatMapping(x -> x.getContainers().stream(), Collectors.toSet())));
如果没有 java-9,你可以这样做:
Map<Long, Set<Long>> result = items.stream()
.flatMap(x -> x.getContainers().stream().map(y -> new SimpleEntry<>(x.getCategory(), y)))
.collect(Collectors.groupingBy(
Entry::getKey,
Collectors.mapping(Entry::getValue, Collectors.toSet())));
你也可以这样做Map#merge
:
Map<Long, Set<Long>> map2 = new HashMap<>();
items.forEach(x -> map2.merge(
x.getCategory(),
x.getContainers(),
(left, right) -> {
left.addAll(right);
return left;
}));
推荐阅读
- javascript - 运行我的 FOAM 网站时获得“GET /favicon.ico HTTP/1.1”404
- c# - 分页和页面冲突 - ASP.Net Core Razor Pages 与 MVC 控制器方法分页冲突
- xamarin - Android 模拟器在 Visual Studio 2017 中非常慢
- c# - System.Drawing.Image 中的内存不足异常
- gnuplot - gnuplot 报告带有日期范围的空 x 范围
- jquery - 405(不允许的方法),在 Web 应用程序中使用 JQuery 和 Ajax
- angularjs - 如何获取包括 ngIf 子范围的 $error 值
- javascript - 如何在 react-draft-wysiwyg 中添加自定义下拉菜单?
- java - 如何按已合并的 id 对 2 个列表的元素进行排序?
- reactjs - JSX 引导程序未终止