使用Stream API对列表中的对象进行分组

时间:2018-05-09 14:47:06

标签: java java-stream

想象一下,我们有POJO类Item

class Item {
    private String key;
    private String $value;

    // constructors, getters & setters
}

在我们的主要课程中,我们有List包含其中一些项目。如何使用Stream API对具有相同key的所有项目进行分组?

我发现Collectors.groupingBy或多或少是我正在寻找的,但它会返回一张地图,我需要保留该项目List

例如,想象一下列表如下:

List [
    Item { key1, value1 },
    Item { key2, value2 },
    Item { key2, value3 }
]

我希望得到一个像以下那样的返回值:

List [
    List [
        Item { key1, value1 }
    ], 
    List [
        Item { key2, value2 },
        Item { key2, value3 }
    ]
]

我不知道它是否有助于了解我为什么要这样做(也许有更好的方法),但我想最终得到一个包含该键和列表的另一个对象的列表使用该密钥的所有项目:

List [
    AnotherObject {
        key1,
         List [
            Item { key1, value1 }
        ]
    },

    AnotherObject {
        key2,
         List [
            Item { key2, value2 },
            Item { key2, value3 }
        ]
    }
]

成为AnotherObject另一个POJO类:

class AnotherObject {
    private String key;
    private List<Item> $items;

    // constructors, getters & setters
}

2 个答案:

答案 0 :(得分:2)

只需将groupBy返回的地图条目映射到您的AnotherObject。

List<AnotherObject> result = items.stream()
     .collect(Collectors.groupingBy(Item::getKey, LinkedHashMap::new, Collectors.toList()))
     .entrySet()
     .stream()
     .map(e -> new AnotherObject(e.getKey(), e.getValue()))
     .collect(Collectors.toList());

答案 1 :(得分:0)

另一种方法是使用toMap收集器:

Collection<AnotherObject> resultSet = items.stream()
            .collect(Collectors.toMap(Item::getKey,
                    f -> new AnotherObject(f.getKey(),
                            new ArrayList<>(Collections.singletonList(f))),
                    (left, right) -> {
                        left.get$items().addAll(right.get$items());
                        return left;
                    }, LinkedHashMap::new)).values();