是否可以通过收集器对每个列表进行操作而不创建中间映射?

joh*_*384 3 java java-8 java-stream

我有以下代码在List上执行分组,然后对每个分组列表进行操作,然后将其转换为单个项目:

Map<Integer, List<Record>> recordsGroupedById = myList.stream()
    .collect(Collectors.groupingBy(r -> r.get("complex_id")));

List<Complex> whatIwant = recordsGroupedById.values().stream().map(this::toComplex)
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

toComplex功能如下:

Complex toComplex(List<Record> records);
Run Code Online (Sandbox Code Playgroud)

我觉得我可以在不创建中间地图的情况下做到这一点,也许使用reduce.有任何想法吗?

输入流按照我想在流中顺序分组的元素进行排序.在正常的循环结构中,我能够确定下一组何时开始并在那时创建一个"复杂".

Bri*_*etz 6

创建一个收集器,它将groupingBy和您的后处理功能结合起来collectingAndThen.

Map<Integer, Complex> map = myList.stream()
    .collect(collectingAndThen(groupingBy(r -> r.get("complex_id"), 
                               Xxx::toComplex));
Run Code Online (Sandbox Code Playgroud)

如果您只想在Collection<Complex>这里,您可以向地图询问它values().

  • 这搞砸了.`groupingBy()`的结果是Map,后处理器必须能够采用预收集器的返回类型.这应该是这样的:`myList.stream().collect(groupingBy(r - > r.get("complex_id"),collectingAndThen(toList(),this :: toComplex)))`.你看,后处理器只用于下游,而不是用于整个结果. (2认同)