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

标签 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;
    }    
}

我必须添加基于年份和名称的目标和已实现列值。

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

所以输出将是:

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

我看过一个例子,说明如果我有一个接受参数的构造函数,我将如何实现这样的目标,但我对这个概念不是很清楚 Group by and sum objects like in SQL with Java lambdas? :

如何仅使用默认构造函数来获得相同类型的 List<Target>但具有多列的计算值?

最佳答案

看来您需要根据三件事进行分组:YearMonthName,因此可能如下所示:

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();

正如 Federico 在评论中提到的,这将改变您在初始 List 中的元素。您可能会接受它,但如果您不满意,则需要将 Function.identity() 替换为一个复制函数,该函数会从现有的 Target 中创建一个新的 Target .

关于Java 8 添加对象列表的多个属性的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52465039/

相关文章:

java - 将数据字符串拆分为多个变量(Java)

java - 沮丧.. lastLocation.getLatitude() 将设置文本但不会启动双重。为此使用 google api

java - iterator.next() 可以从源中删除元素吗? ( java )

java - executor.invokeAll() 未完成执行

Java 8 Stream Reduce 任意类类型

java - 分组对象java 8

java - 如何用纯JPA实现历史表?

java - 我可以访问流链中先前 lambda 的值吗?

Java 11 局部变量类型推断改进用法

java - MethodHandles 还是 LambdaMetafactory?