I have a list of Student objects.
It is required to get create a new list which should be having sum of their marks.
Preferred if this can be done using 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;
}
I get below exception
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)
CodePudding user response:
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 "}";
}
}
Output:
[{1, "A", 70}, {2, "B", 90}]