4 回答
TA贡献1777条经验 获得超3个赞
您可以将toMap
收集器与有界方法引用一起使用来获取您需要的内容。另请注意,此解决方案假设您的源容器中没有重复的 A 实例。如果该前提条件成立,则该解决方案将为您提供所需的结果。它看起来是这样的。
Map<A, Collection<B>> resultMap = listofA.stream() .collect(Collectors.toMap(Function.identity(), repo::getListofB);
如果您有重复的 A 元素,那么除了上面给出的功能之外,您还必须使用此合并功能。合并功能可以处理键冲突(如果有)。
Map<A, Collection<B>> resultMap = listofA.stream() .collect(Collectors.toMap(Function.identity(), repo::getListofB, (a, b) -> { a.addAll(b); return a; }));
这里有一个更简洁的 Java9 方法,它使用flatMapping
收集器来处理重复的 A 元素。
Map<A, List<B>> aToBmap = listofA.stream() .collect(Collectors.groupingBy(Function.identity(), Collectors.flatMapping(a -> getListofB(a).stream(), Collectors.toList())));
TA贡献1772条经验 获得超5个赞
这将是直截了当的,
listofA.stream().collect(toMap(Function.identity(), a -> getListofB(a)));
TA贡献1772条经验 获得超8个赞
在这个答案中,我将展示如果列表中有重复A
元素会发生什么List<A> listofA
。
实际上,如果 中存在重复项listofA
,下面的代码将抛出一个IllegalStateException
:
Map<A, Collection<B>> resultMap = listofA.stream() .collect(Collectors.toMap( Function.identity(), repo::getListofB);
可能会抛出异常,因为当键中存在冲突时Collectors.toMap
不知道如何合并Function.identity()
值(即当键映射器函数返回重复项时,如果列表中存在重复元素就会出现这种情况listofA
)。
文档中明确指出了这一点:
如果映射的键包含重复项(根据
Object.equals(Object)
),则IllegalStateException
在执行收集操作时会抛出异常。如果映射的键可能有重复项,请使用toMap(Function, Function, BinaryOperator
) 代替。
文档还为我们提供了解决方案:如果存在重复元素,我们需要提供一种合并值的方法。这是一种这样的方式:
Map<A, Collection<B>> resultMap = listofA.stream() .collect(Collectors.toMap( Function.identity(), a -> new ArrayList<>(repo.getListofB(a)), (left, right) -> { left.addAll(right); return left; });
Collectors.toMap
它使用接受合并函数作为其第三个参数的重载版本。在合并函数中,Collection.addAll
用于将B
每个重复A
元素的元素添加到每个 的唯一列表中A
。
在值映射器函数中,ArrayList
创建了一个新值,因此List<B>
每个值的原始值A
都不会发生变化。另外,当我们创建一个 时Arraylist
,我们提前知道它可以被改变(即我们可以稍后向其中添加元素,以防 中存在重复项listofA
)。
TA贡献1998条经验 获得超6个赞
要收集一个Map
其中键是A
未更改的对象,值是对应B
对象的列表,可以将toList()
收集器替换为以下收集器:
toMap(Function.identity(), a -> repo.getListOfB(a))
第一个参数定义如何从原始对象计算密钥identity()
:保持流的原始对象不变。
第二个参数定义了如何计算该值,因此这里它仅包含对将 a 转换A
为 的列表的方法的调用B
。
由于该repo
方法仅采用一个参数,因此您还可以通过用方法引用替换 lambda 来提高清晰度:
toMap(Function.identity(), repo::getListOfB)
添加回答
举报