Tim*_*lbe 22 java java-8 collectors
我想创建一个Map从List的PointS和有地图从里面用相同的parentId,如映射列表中的所有条目Map<Long, List<Point>>.
我用过Collectors.toMap()但不编译:
Map<Long, List<Point>> pointByParentId = chargePoints.stream()
.collect(Collectors.toMap(Point::getParentId, c -> c));
Run Code Online (Sandbox Code Playgroud)
dav*_*xxx 59
TLDR:
要Map通过key(Map<MyKey,MyObject>)收集包含单个值的内容,请使用Collectors.toMap().
要Map通过key(Map<MyKey, List<MyObject>>)收集包含多个值的内容,请使用Collectors.groupingBy().
Collectors.toMap()
通过写:
chargePoints.stream().collect(Collectors.toMap(Point::getParentId, c -> c));
Run Code Online (Sandbox Code Playgroud)
返回的对象将具有该Map<Long,Point>类型.
查看Collectors.toMap()您正在使用的功能:
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper)
Run Code Online (Sandbox Code Playgroud)
它返回a Collector作为结果Map<K,U>where K和U是传递给方法的两个函数的返回类型.在你的情况下,Point::getParentId是一个龙,并c指一个Point.而 应用Map<Long,Point>时返回的collect()是.
Collectors.toMap() javadoc指出这种行为很可取:
返回一个
Collector积累元素的元素,Map其键和值是将提供的映射函数应用于输入元素的结果.
但是如果映射的键包含重复项(根据Object.equals(Object)),IllegalStateException则抛出一个
可能是您的情况,因为您将Point根据特定属性对s进行分组:parentId.
如果映射的键可能有重复,您可以使用toMap(Function, Function, BinaryOperator)重载,但它不会真正解决您的问题,因为它不会将元素分组相同parentId.它只是提供了一种不具有两个相同元素的方法parentId.
Collectors.groupingBy()
为了满足您的要求,您应该使用Collectors.groupingBy()哪种行为和方法声明更符合您的需求:
public static <T, K> Collector<T, ?, Map<K, List<T>>>
groupingBy(Function<? super T, ? extends K> classifier)
Run Code Online (Sandbox Code Playgroud)
它被指定为:
返回一个收集器,对T类型的输入元素执行"group by"操作,根据分类函数对元素进行分组,并将结果返回到Map中.
该方法需要一个Function.
在您的情况下,Function参数是Point(typeStream的),并且Point.getParentId()您希望按parentId值对元素进行分组.
所以你可以写:
Map<Long, List<Point>> pointByParentId =
chargePoints.stream()
.collect(Collectors.groupingBy( p -> p.getParentId()));
Run Code Online (Sandbox Code Playgroud)
或者使用方法参考:
Map<Long, List<Point>> pointByParentId =
chargePoints.stream()
.collect(Collectors.groupingBy(Point::getParentId));
Run Code Online (Sandbox Code Playgroud)
Collectors.groupingBy():走得更远
事实上,groupingBy()收藏家比实际例子更进一步.该Collectors.groupingBy(Function<? super T, ? extends K> classifier)方法是最后只存储所收集的值的简便方法Map的List.
要存储Map除了List或存储特定计算结果之外的其他内容的值,groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream)您应该感兴趣.
例如 :
Map<Long, Set<Point>> pointByParentId =
chargePoints.stream()
.collect(Collectors.groupingBy(Point::getParentId, toSet()));
Run Code Online (Sandbox Code Playgroud)
因此,除了提出的问题之外,您应该考虑groupingBy()选择要存储到收集的值中的灵活方式Map,明确toMap()不是.
| 归档时间: |
|
| 查看次数: |
30134 次 |
| 最近记录: |