首页 > 解决方案 > 在 Java 8 中使用流减少 bean 列表

问题描述

想象一下,您有一个包含多个属性的 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,实例属性除了类型之外具有完全相同的值。

有没有办法使用流来做到这一点?

标签: javajava-stream

解决方案


首先,将集合分组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]))
    );
}

推荐阅读