Stream API的直接方法涉及2条Stream管道:
- 第一个创建一个临时
Map<Long, List<Long>>
的stackId
到questionIds
。这是通过groupingBy(classifier, downstream)
收集器完成的,在收集器中我们根据对进行分类,stackId
并将具有相同值的值stackId
映射到它们的questionId
(和mapping
),并使用收集到列表中toList()
。 - 第二个将该映射的每个条目转换为一个
MyOtherClass
实例,并将其收集到一个列表中。
假设您有一个构造函数
MyOtherClass(Long stackId, Collection<Long> questionIds),示例代码将是:
Map<Long, List<Long>> map = list.stream() .collect(Collectors.groupingBy( MyClass::getStackId, Collectors.mapping(MyClass::getQuestionId, Collectors.toList()) ));List<MyOtherClass> result = map.entrySet() .stream() .map(e -> new MyOtherClass(e.getKey(), e.getValue())) .collect(Collectors.toList());
使用StreamEx库,您可以在单个Stream管道中执行此操作。该库提供了
pairing和
first收集器。这样可以配对两个收集器,并对两个收集的结果执行整理器操作:
- 第一个仅保留
stackId
分组元素中的第一个(根据构造,它们将全部相同) - 第二个将每个元素映射到它们
questionId
并收集到一个列表中。 - 整理程序操作仅返回的新实例
MyOtherClass
。
样例代码:
import static java.util.stream.Collectors.collectingAndThen;import static java.util.stream.Collectors.mapping;import static java.util.stream.Collectors.toList;import static one.util.streamex.MoreCollectors.first;import static one.util.streamex.MoreCollectors.pairing;// ...Collection<MyOtherClass> result = StreamEx.of(list) .groupingBy( MyClass::getStackId, pairing( collectingAndThen(mapping(MyClass::getStackId, first()), Optional::get), mapping(MyClass::getQuestionId, toList()), MyOtherClass::new ) ).values();



