Using Java 8 threads to aggregate list objects

We use 3 lists ListA, ListB, ListC to save marks for 10 students in 3 subjects (A, B, C).

Subjects B and C are optional, so only a few out of 10 students have marks on these subjects

Class Student{
String studentName;
int marks;
}

ListA has entries for 10 students, ListB for 5 and ListC for 3 (which is also the size of the lists)

Want to know how we can summarize student grades for our subjects using java 8 steam.

I tried the following

List<Integer> list = IntStream.range(0,listA.size() -1).mapToObj(i -> listA.get(i).getMarks() + 
listB.get(i).getMarks() + 
listC.get(i).getMarks()).collect(Collectors.toList());;

There are 2 problems with this

a) It will throw an IndexOutOfBoundsException, since listB and listC do not have 10 elements

b) The return list is if is of type Integer and I want it to be of type Student.

Any inputs will be very helpful.

+4
source share
2

3 , flatMap, . , . - :

Map<String, Integer> studentMap = Stream.of(listA, listB, listC)
        .flatMap(Collection::stream)
        .collect(groupingBy(student -> student.name, summingInt(student -> student.mark)));

, Student getters , , :

Map<String, Integer> studentMap = Stream.of(listA, listB, listC)
        .flatMap(Collection::stream)
        .collect(groupingBy(Student::getName, summingInt(Student::getMark)));

, studentMap:

studentMap.forEach((key, value) -> System.out.println(key + " - " + value));

Student, ( , Student all-args ):

List<Student> studentList = Stream.of(listA, listB, listC)
        .flatMap(Collection::stream)
        .collect(groupingBy(Student::getName, summingInt(Student::getMark)))
        .entrySet().stream()
            .map(mapEntry -> new Student(mapEntry.getKey(), mapEntry.getValue()))
            .collect(toList());
+4

:

Map<String, Student> result = Stream.of(listA, listB, listC)
    .flatMap(List::stream)
    .collect(Collectors.toMap(
        Student::getName, // key: student name
        s -> new Student(s.getName(), s.getMarks()), // value: new Student
        (s1, s2) -> { // merge students with same name: sum marks
            s1.setMarks(s1.getMarks() + s2.getMarks());
            return s1;
        }));

Collectors.toMap ( , Student, ).

Collectors.toMap :

  • , ( Student::getName)
  • , ( Student, , , )
  • , , , , ( ).

Student:

public Student(Student another) {
    this.name = another.name;
    this.marks = another.marks;
}

public Student merge(Student another) {
    this.marks += another.marks;
    return this;
}

:

Map<String, Student> result = Stream.of(listA, listB, listC)
    .flatMap(List::stream)
    .collect(Collectors.toMap(
        Student::getName,
        Student::new,
        Student::merge));
+1

Source: https://habr.com/ru/post/1676538/


All Articles