【问题标题】:In ArrayList, group by a key and perform summation over one of the values在 ArrayList 中,按键分组并对其中一个值执行求和
【发布时间】:2022-09-23 16:09:08
【问题描述】:

我有一个学生对象列表。

需要创建一个新列表,该列表应该具有他们的分数总和。

如果可以使用Java-8 完成,则首选

public class Test {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        list.add(new Student(1, \"A\", 10));
        list.add(new Student(1, \"A\", 20));
        list.add(new Student(1, \"A\", 10));
        list.add(new Student(1, \"A\", 30));
        list.add(new Student(2, \"B\", 40));
        list.add(new Student(2, \"B\", 50));

        Map<String, List<Student>> map = list
                .stream()
                .collect(Collectors.groupingBy(Student::getName));
        System.out.println(map);  // not getting desired result
        
        // Expected Output
        // list [{1, \"A\", 70}, {2, \"B\", 90}]

    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Student {
    int id;
    String name;
    int marks;
}

我得到以下异常

Exception in thread \"main\" java.lang.IllegalStateException: Duplicate key 1 (attempted merging values Student(id=1, name=A, marks=10) and Student(id=1, name=A, marks=20))
    at java.base/java.util.stream.Collectors.duplicateKeyException(Collectors.java:135)
    at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:182)
    at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
    at com.tara.cas.service.Test.main(Test.java:22)

  • 你到底卡在哪里了?您似乎忘记了在当前解决方案中对分数求和,第一个 stream 是什么?

标签: java group-by java-8


【解决方案1】:
public class Test {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        list.add(new Student(1, "A", 10));
        list.add(new Student(1, "A", 20));
        list.add(new Student(1, "A", 10));
        list.add(new Student(1, "A", 30));
        list.add(new Student(2, "B", 40));
        list.add(new Student(2, "B", 50));

        Map<Integer, Student> map = list.stream().collect(Collectors.toMap(Student::getId, Function.identity(),
                (existing, replacement) -> {
                    existing.setMarks(existing.getMarks()+replacement.getMarks());
                    return existing;
                }));

        System.out.println(map.values());
    }
}

class Student {
    int id;
    String name;
    int marks;

    public Student(int id, String name, int marks) {
        this.id = id;
        this.name = name;
        this.marks = marks;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getMarks() {
        return marks;
    }

    public void setMarks(int marks) {
        this.marks = marks;
    }

    @Override
    public String toString() {
        return "{"+id+", \""+name+"\", "+marks+"}";
    }
}

输出:

[{1, "A", 70}, {2, "B", 90}]

【讨论】:

    猜你喜欢
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 2023-03-28
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    相关资源
    最近更新 更多