TLDR :
若要按键 () 收集到包含单个值的 中,请使用 Collectors.toMap()。
。
若要按键 () 收集到包含多个值的 中,请使用 Collectors.groupingBy()
。Map
Map<MyKey,MyObject>
Map
Map<MyKey, List<MyObject>>
Collectors.toMap()
通过写 :
chargePoints.stream().collect(Collectors.toMap(Point::getParentId, c -> c));
返回的对象将具有该类型。
查看您正在使用的函数:Map<Long,Point>
Collectors.toMap()
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper)
它返回 with 作为结果,其中 和 是传递给该方法的两个函数的返回类型。在您的情况下,是一个 Long,指的是 .而返回的时间是应用 on。Collector
Map<K,U>
K
U
Point::getParentId
c
Point
Map<Long,Point>
collect()
这种行为是意料之中的,因为 Collectors.toMap() javadoc 声明:
返回 将元素累积到 a 中的 a,其键和值是将提供的映射函数应用于输入元素的结果。Collector
Map
但是,如果映射的键包含重复项(根据 ),则可能会抛出
a,这可能是您的情况,因为您将根据特定属性对 s 进行分组:。Object.equals(Object)
IllegalStateException
Point
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)
它被指定为:
返回一个收集器,该收集器对 T 类型的输入元素实现“分组依据”操作,根据分类函数对元素进行分组,并在 Map 中返回结果。
该方法采用 .
在您的例子中,参数是(Stream 的 ),并且您可以返回,因为您希望按值对元素进行分组。Function
Function
Point
type
Point.getParentId()
parentId
所以你可以写:
Map<Long, List<Point>> pointByParentId =
chargePoints.stream()
.collect(Collectors.groupingBy( p -> p.getParentId()));
或者使用方法参考:
Map<Long, List<Point>> pointByParentId =
chargePoints.stream()
.collect(Collectors.groupingBy(Point::getParentId));
Collectors.groupingBy() : 走得更远
事实上,收集器比实际示例走得更远。该方法最终只是一种将收集的值存储在 .
要将 的值存储在另一个事物中,而不是 a 或 存储特定计算的结果,您应该会感兴趣。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()));
因此,除了所提出的问题之外,您应该考虑一种灵活的方式来选择要存储到收集的值中,最终不是。groupingBy()
Map
toMap()