Java 8添加了对象列表的多个属性的值

Suj*_*jal 9 java lambda java-8 java-stream

可以说我下面有一个类有getter和setter但只有默认构造函数.

注意:我不允许更改此类的结构.

class Target {

    private String year;
    private String month;
    private String name;
    private double target;
    private double achieved;


    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    public String getMonth() {
        return month;
    }

    public void setMonth(String month) {
        this.month = month;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getTarget() {
        return target;
    }

    public void setTarget(double target) {
        this.target = target;
    }

    public double getAchieved() {
        return achieved;
    }

    public void setAchieved(double achieved) {
        this.achieved = achieved;
    }    
}
Run Code Online (Sandbox Code Playgroud)

我必须根据年份和名称添加Target和Achieved列值.

Year Month Name Target Achieved
2018  8    Joey 50.00   10.00
2018  9    Joey 200.00  100.00
2018  9    Fred 200.00  150.00
2018  9    Fred 20.00   50.00
Run Code Online (Sandbox Code Playgroud)

所以输出将是:

Year Month Name Target  Achieved
2018  8    Joey 50.00   10.00
2018  9    Joey 200.00  100.00
2018  9    Fred 220.00  200.00
Run Code Online (Sandbox Code Playgroud)

我已经看到了一个关于如何实现这样的事情的例子,如果我有一个接受参数的构造函数,但是我对于概念Group by并没有那么清楚,并且在SQL中使用Java lambdas来汇总对象?:

如何使用默认构造函数实现此目的,以获得相同类型List<Target>但具有多列的计算值?

Eug*_*ene 9

看来你需要组基于三点:Year,MonthName,所以这可能是这样的:

Collection<Target> merged = yourListOfTargets
            .stream()
            .collect(Collectors.toMap(
                    t -> List.of(t.getYear(), t.getMonth(), t.getName()),
                    Function.identity(),
                    (left, right) -> {
                        left.setTarget(left.getTarget() + right.getTarget());
                        left.setAchieved(left.getAchieved() + right.getAchieved());
                        return left;
                    }))
            .values();
Run Code Online (Sandbox Code Playgroud)

正如费德里科在评论中提到的那样,这将改变你最初的元素List.您可能没问题,但如果不是,则需要Function.identity()使用复制功能替换,该功能Target将从现有功能创建新功能.