【问题标题】:Grouping list of objects and reduce subgroups into different objects in Java 8在Java 8中将对象列表分组并将子组减少为不同的对象
【发布时间】:2019-12-11 17:34:59
【问题描述】:

我需要将对象列表转换为不同类型的分组对象列表。

public class Person {
private String name;
private String dept;
private int amount;
    //constructors
    //getters and setters
}


public class GroupedPersons {

private String dept;
private int sumAmount;
private List<Person> personsOfDept; 

    // how should be the constructor??
    //getters and setters
}  


List<Person> persons = Arrays.asList(
            new Person("Mark", "Sales", 100),
            new Person("Rob", "Marketing", 200),
            new Person("Kyle", "Sales", 150),
            new Person("Jack", "Accounts", 50),
            new Person("Sam", "Sales", 150),
            new Person("Jeff", "Marketing", 200));

我需要结果为

List<GroupedPersons> 

["Sales",400,List<Person>]
["Marketing",400,List<Person>]
["Accounts",50,List<Person>]

我试过了

Map<String,List<Person>> deptMap = persons.stream().collect(Collectors.groupingBy(Person::getDept));

但无法将地图减少到我需要的对象列表。

【问题讨论】:

    标签: java list object java-stream transform


    【解决方案1】:

    我们可以为 GroupedPersons 类使用构造函数,该类将采用 deptsumAmountpersonsOfDept 列表,如下所示:

    class GroupedPersons {
    
        private String dept;
        private int sumAmount;
        private List<Person> personsOfDept;
    
        public GroupedPersons(String dept, int sumAmount, List<Person> personsOfDept) {
            this.dept = dept;
            this.sumAmount = sumAmount;
            this.personsOfDept = personsOfDept;
        }
    }
    

    然后我们可以使用以下逻辑首先得到Persondept完成的分组,这将导致Map&lt;String, List&lt;Person&gt;&gt;,然后使用来自映射的entrySet().stream()的流来求和amount 并从Map.Entry&lt;String, List&lt;Person&gt;&gt;.getValue() 获取List&lt;Person&gt;

     List<GroupedPersons> list = persons.stream()
                                        .collect(Collectors.groupingBy(p -> p.getDept()))
                                        .entrySet()
                                        .stream()
                                        .map(ent -> new GroupedPersons(
                                                    ent.getKey(),
                                      ent.getValue().stream().mapToInt(p -> p.getAmount()).sum(),
                                                    ent.getValue()))
                                        .collect(Collectors.toList());
    

    【讨论】:

    • p -&gt; p.getDepth() 这样的片段应该替换为Person::getDepth 以获得更好的可读性。 p -&gt; p.getAmount() 也一样。
    • 如果 sumAmount 的类型为 BigInteger..as .sum() 不可用,我们如何在构造函数参数中求和
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    • 2018-07-18
    相关资源
    最近更新 更多