使用Java 8中的流来减少be​​an的列表

时间:2018-09-20 15:35:26

标签: java java-stream

想象一下,您有一个具有多个属性的bean数组列表:

class Item {
    public int id;
    public String type;
    public String prop1;
    public String prop2;
    public String prop3;
}

您有一个具有以下值的列表:

id | type| prop1| prop2| prop3
1  | A   | D    | E    | F
1  | B   | D    | E    | F
2  | A   | G    | H    | I
2  | B   | G    | H    | I
2  | C   | G    | H    | I

我想将其简化为包含以下内容的列表:

id | type    | prop1| prop2| prop3  
1  | A, B    | D    | E    | F
2  | A, B, C | G    | H    | I

请注意,对于相同的ID,实例属性具有与类型完全相同的值。

有没有一种方法可以使用流?

1 个答案:

答案 0 :(得分:2)

首先,将集合按Item::getId分组,然后将结果保存到Map<Integer, List<String>>。其次,将每个条目变成一个项目,并将它们收集在结果列表中。

List<Item> result = list
    .stream()
    // build a Map<Integer, List<String>>
    .collect(Collectors.groupingBy(Item::getId, Collectors.mapping(Item::getType, Collectors.toList())))
    .entrySet()
    .stream()
    // transform an entry to an item
    .map(i -> new Item(i.getKey(), String.join(", ", i.getValue().toArray(new String[0]))))
    .collect(Collectors.toList());

要清理流链,可以在单独的方法中移动构造逻辑,并使用对该方法的引用(例如map(Item::fromEntry)

public static Item fromEntry(Map.Entry<Integer, List<String>> entry) {
    return new Item(
        entry.getKey(),
        String.join(", ", entry.getValue().toArray(new String[0]))
    );
}