我有一个包含以下字段的类:
public class Item{
private String name;
private Long category;
private Set containers;
}
我需要做的是转一个
列表与LT;项目>项目
进入
Map< Long / * categoryID * /,Set< Long / * Containers * />>
使用Java 8 Stream API.
现在我可以使用Itarable和一些if得到相同的结果,如下所示:
List items = getItems();
Iterator itemsIterator = items.iterator();
Map> containersByCategoryMap = new HashMap<>();
while (itemsIterator.hasNext()) {
Item item = itemsIterator.next();
Long category = item.getCategory();
Set containers = item.getContainers();
if (containersByCategoryMap.containsKey(category)) {
Set containersByCategory = containersByCategoryMap.get(category);
containersByCategory.addAll(containers);
} else {
Set 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> map = items.stream()
.collect(Collectors.groupingBy(
Item::getCategory,
Collectors.flatMapping(x -> x.getContainers().stream(), Collectors.toSet())));
没有java-9,你可以这样做:
Map> 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> map2 = new HashMap<>();
items.forEach(x -> map2.merge(
x.getCategory(),
x.getContainers(),
(left, right) -> {
left.addAll(right);
return left;
}));
标签:java,java-8,java-stream,list,dictionary
来源: https://codeday.me/bug/20190828/1746621.html