我想从点
的列表
中创建一个映射
并在映射中使用相同的parentId映射列表中的所有条目,如映射
。
我使用了Collectors.tomap()
但它不编译:
Map<Long, List<Point>> pointByParentId = chargePoints.stream()
.collect(Collectors.toMap(Point::getParentId, c -> c));
TLDR:
若要收集到按键包含单个值的映射
中(映射
),请使用Collectors.tomap()
。
若要收集到按键包含多个值的映射
(映射
),请使用Collectors.GroupingBy()
。
collectors.tomap()
chargePoints.stream().collect(Collectors.toMap(Point::getParentId, c -> c));
返回的对象将具有map
类型。
查看正在使用的collectors.tomap()
函数:
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper)
它返回一个收集器
,结果为映射
,其中k
和u
是传递给方法的两个函数的返回类型。在您的示例中,point::GetParentId
是长的,而C
指的是point
。而在应用collection()
时返回的map
。
而且这种行为是预期的,因为Collectors.tomap()javadoc声明:
如果映射的键可能有重复项,您可以使用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的输入元素执行“GROUP BY”操作,根据分类函数对元素进行分组,并在映射中返回结果。
该方法采用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():进一步
实际上,groupingby()
收集器比实际示例更进一步。Collectors.GroupingBy(Function<?super T,?extends k>classifier)
方法最终只是一种将收集的映射
的值存储在列表
中的方便方法。
要将映射
的值存储在列表
之外的其他东西中或存储特定计算的结果,GroupingBy(Function<?super T,?extends k>classifier,collector<?super T,?extends k>classifier,collector<?super T,a,d>downdown)
应该会引起您的兴趣。
例如:
Map<Long, Set<Point>> pointByParentId =
chargePoints.stream()
.collect(Collectors.groupingBy(Point::getParentId, toSet()));
因此,除了所问的问题之外,您应该考虑groupingby()
作为一种灵活的方法来选择要存储到收集的map
中的值,而tomap()
绝对不是这样。
假设你有一张这样的物体地图(尽管想象它更大): rtype=133,有两个! 我想对Streams做的是这样的: 我在理解Collectors&groupBy的工作原理时遇到了一些麻烦,但我想这可能会用于本例。 在Java streams API中进行编码的正确方法是什么? 我很难找到类似的地图例子(人们在他们的例子中更多地使用列表)
我正在使用Java8lambda,并希望使用返回。我所能想到的最好方法是使用等于的虚拟和调用以下
我有两个列表,我必须从它们创建一个地图。首先,我在迭代for loop,其次,我想通过一个stream和collect来映射,但我不知道在这种情况下如何使用collectors.tomap。有可能吗?
我试图使用流API代替循环,并有以下问题。 我有一个方法,它接受一个Enum并返回一个SortedMap。我将每个映射存储在一个列表中,但是我现在希望将每个SortedMap存储在一个映射中,Enum名称为键,从返回的SortedMap作为值,如何使用流API执行此操作? 当前工作列表方法 我使用收集器的错误尝试。toMap。。 工作回路,工作回路
以下代码 由IntelliJ转换为: 可以缩短为 这两个流版本不编译。 IntelliJ,暗示值中的i存在问题[i]: 不兼容的类型 必需:int找到:java。lang.对象 编译器抱怨: 错误:(35,17)java:接口java中的方法collect。util。流动IntStream不能应用于给定类型 必需:java。util。作用供应商,爪哇。util。作用ObjIntConsumer,j