【发布时间】:2016-01-14 00:12:11
【问题描述】:
我有一个来自 Google Places API 的 Google PlaceSummary 对象列表。我想按他们的 Google Place ID 收集和分组它们,但也保留元素的顺序。我认为可行的是:
Map<String, List<PlaceSummary>> placesGroupedByPlaceId =
places.stream()
.collect(Collectors.groupingBy(
PlaceSummary::getPlaceId,
LinkedHashMap::new,
Collectors.mapping(PlaceSummary::getPlaceId, toList())
));
但它甚至不会编译。看起来应该根据Java API documentation on Collectors.
以前我有这个代码:
Map<String, List<PlaceSummary>> placesGroupedByPlaceId = places.stream()
.collect(Collectors.groupingBy(PlaceSummary::getPlaceId));
但是,Streams API 上的标准 .collect() 不保留后续 HashMap 中的元素顺序(显然,因为 HashMaps 是无序的)。我希望输出是LinkedHashMap,以便地图按每个桶的插入顺序排序。
但是,我建议的解决方案无法编译。首先,它不能识别PlaceSummary::getPlaceId,因为它说它不是一个函数——尽管我知道它是。其次,它说我不能将LinkedHashMap<Object, Object> 转换为 M。M 应该是一个通用集合,所以它应该被接受。
如何使用 Java Stream API 将 List 转换为 LinkedHashMap?有没有简洁的方法来做到这一点?如果太难理解,我可能会求助于 Java 8 之前的老式方法。
我注意到有 another Stack Overflow answer on converting List to LinkedHashMap,但这没有我想要的解决方案,因为我需要收集“这个”我专门迭代的对象。
【问题讨论】:
-
从docs.oracle.com/javase/8/docs/api/java/util/stream/… 中给出的示例看来,它应该可以编译。可能是
Collectors.toList()而不是toList(),除非你是静态导入的? -
@njzk2 我不认为 toList 是问题 - 正如你所说,这是静态导入的。 LinkedHashMap::new 行在 IntelliJ 中有以下错误:方法引用中的错误返回类型:无法将 java.util.LinkedHashMap
转换为 M -
映射收集器应用于这些值,因此您需要 p -> p 而不是 PlaceSummary::getPlaceId
-
@AlexisC。所以那将是 p -> p.getPlaceId ?所以...这是否意味着我可以只使用 p -> p 来指代“this”元素?
-
No p -> p.getPlaceId 表示 PlaceSummary 分组值将通过其地点 ID 进行映射。如果你想要实例本身,只需应用标识函数 p -> p。
标签: java java-8 java-stream linkedhashmap collectors