在ArrayList中,按键分组,然后对其中一个值进行求和



我有一个Student对象列表。

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

如果可以使用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)
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}]

最新更新