遍历Java 8 Grouping中的Collected列表

时间:2018-08-23 03:52:18

标签: java-8

我有一个对象列表,说List<Type1>是我使用type进行分组的。(使用groupingBy) 现在,我想将Map>转换为同时具有该组的列表和ID的Type2。

class Type1{
int id;
int type;
String name;
}

class Type2{
int type;
List<Type1> type1List;
}

这是我为实现此目的而写的:

myCustomList
            .stream()
            .collect(groupingBy(Type1::getType))
            .entrySet()
            .stream()
            .map(type1Item -> new Type2() {
                {
                    setType(type1Item.getKey());
                    setType1List(type1Item.getValue());
                }
            })
            .collect(Collectors.toList());

这很好用。但是我正在尝试使代码更加简洁。有没有一种方法可以避免这种情况再次发生,并使用某种平面图来实现。

3 个答案:

答案 0 :(得分:2)

您可以将整理器功能传递给collectingAndThen,以在形成初始map之后完成工作。

List<Type2> result = myCustomList.stream()
    .collect(Collectors.collectingAndThen(Collectors.groupingBy(Type1::getType),
        m -> m.entrySet().stream()
            .map(e -> new Type2(e.getKey(), e.getValue()))
            .collect(Collectors.toList())));

答案 1 :(得分:1)

您应为Type2提供以下形式的构造函数

Type2(int type, List<Type1> type1List) {
    this.type = type;
    this.type1List = type1List;
}

然后,您可以写.map(type1Item -> new Type2(type1Item.getKey(), type1Item.getValue()))代替

.map(type1Item -> new Type2() {
    {
        setType(type1Item.getKey());
        setType1List(type1Item.getValue());
    }
})

另请参见What is Double Brace initialization in Java?
简而言之,这会造成内存泄漏,因为它会创建Type2的子类,从而捕获type1Item的整个生命周期。

但是您可以作为groupingBy下游收集器的一部分执行转换。这意味着您必须使toList明确,以便通过collectingAndThen将其与随后的映射结合起来:

Collection<Type2> collect = myCustomList
    .stream()
    .collect(groupingBy(Type1::getType,
        collectingAndThen(toList(), l -> new Type2(l.get(0).getType(), l))))
    .values();

如果您确实需要List,则可以使用

List<Type2> collect = myCustomList
    .stream()
    .collect(collectingAndThen(groupingBy(Type1::getType,
            collectingAndThen(toList(), l -> new Type2(l.get(0).getType(), l))),
        m -> new ArrayList<>(m.values())));

答案 2 :(得分:0)

您可以执行以下操作:

type1.map( type1Item -> new Type2(
     type1Item.getKey(), type1Item
)).collect(Collectors.toList());