Using Java 8 streams for aggregating list objects

java-8

Solution

You can make a stream of the 3 lists and then call `flatMap` to put all the lists' elements into a single stream. That stream will contain one element per student per mark, so you will have to aggregate the result by student name. Something along the lines of:

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

Alternatively, if your `Student` class has getters for its fields, you can change the last line to make it more readable:

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

Then check the result by printing out the `studentMap`:

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

If you want to create a list of `Student` objects instead, you can use the result of the first map and create a new stream from its entries (this particular example assumes your `Student` class has an all-args constructor so you can one-line it):

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

Problem

We are using 3 lists ListA,ListB,ListC to keep the marks for 10 students in 3 subjects (A,B,C). Subject B and C are optional, so only few students out of 10 have marks in those subjects ``` Class Student{ String studentName; int marks; } ``` ListA has records for 10 students, ListB for 5 and ListC for 3 (which is also the size of the lists) Want to know how we can sum up the marks of the students for their 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 issues with this a) It will give IndexOutOfBoundsException as listB and listC don't have 10 elements b) The returned list if of type Integer and I want it to be of type Student. Any inputs will be very helpful

Original source

Related problems