Jam*_*phy 18 java linkedhashmap java-8 java-stream collectors
我有一个从Google Places API中获取的Google PlaceSummary对象列表.我想通过他们的Google商家信息ID收集和分组,但也保留元素的顺序.我认为会起作用的是:
Map<String, List<PlaceSummary>> placesGroupedByPlaceId =
places.stream()
.collect(Collectors.groupingBy(
PlaceSummary::getPlaceId,
LinkedHashMap::new,
Collectors.mapping(PlaceSummary::getPlaceId, toList())
));
Run Code Online (Sandbox Code Playgroud)
但它甚至不会编译.它看起来应该根据收集器上的Java API文档.
以前我有这个代码:
Map<String, List<PlaceSummary>> placesGroupedByPlaceId = places.stream()
.collect(Collectors.groupingBy(PlaceSummary::getPlaceId));
Run Code Online (Sandbox Code Playgroud)
但是.collect(),Streams API上的标准不保留后续元素的顺序HashMap(显然因为HashMaps是无序的).我希望输出为a,LinkedHashMap以便Map按每个桶的插入顺序排序.
但是,我建议的解决方案不能编译.首先,它不承认PlaceSummary::getPlaceId它,因为它说它不是一个功能 - 即使我知道它是.其次,它说我不能转换LinkedHashMap<Object, Object>成M. M应该是一个通用的集合,所以它应该被接受.
如何将List转换为LinkedHashMap使用Java Stream API?有简洁的方法吗?如果它太难理解我可能只是采用旧学前Java 8方法.
我注意到在将List转换为LinkedHashMap时还有另一个Stack Overflow答案,但是这没有我想要的解决方案,因为我需要收集'this'我正在迭代的对象.
Tun*_*aki 19
你真的很接近你想要的:
Map<String, List<PlaceSummary>> placesGroupedByPlaceId =
places.stream()
.collect(Collectors.groupingBy(
PlaceSummary::getPlaceId,
LinkedHashMap::new,
Collectors.mapping(Function.identity(), Collectors.toList())
));
Run Code Online (Sandbox Code Playgroud)
在该Collectors.mapping方法中,您需要提供PlaceSummary实例而不是地点ID.在上面的代码中,我使用了Function.identity():这个收集器用于构建值,因此我们需要累积位置本身(而不是它们的ID).
请注意,可以直接写入Collectors.toList()而不是Collectors.mapping(Function.identity(), Collectors.toList()).
到目前为止你的代码没有编译,因为它实际上创建了一个Map<String, List<String>>:你正在为每个ID累积ID(这很奇怪).
您可以将其写为通用方法:
private static <K, V> Map<K, List<V>> groupByOrdered(List<V> list, Function<V, K> keyFunction) {
return list.stream()
.collect(Collectors.groupingBy(
keyFunction,
LinkedHashMap::new,
Collectors.toList()
));
}
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
Map<String, List<PlaceSummary>> placesGroupedById = groupByOrdered(places, PlaceSummary::getPlaceId);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7100 次 |
| 最近记录: |