Transform a List<Object> to a Map such that the String is not a duplicate value using Java 8 Streams

后端 未结 4 649
盖世英雄少女心
盖世英雄少女心 2021-01-12 16:02

We have a Student class as follows:

class Student {
    private int marks;
    private String studentName;

    public int getMarks() {
        r         


        
相关标签:
4条回答
  • 2021-01-12 16:54

    That's because of an incorrect merge function, you should instead use:

    Map<String, Integer> map = studentList.stream()
            .collect(Collectors.toMap(
                    student -> student.getStudentName().toLowerCase(),
                    Student::getMarks,
                    (s1, s2) -> s1 + s2, // add values when merging
                    LinkedHashMap::new));
    
    0 讨论(0)
  • 2021-01-12 16:59

    Your merge function is incorrect. It could be either (s1, s2) -> s1 + s2 or just Integer::sum if you'd rather use a method reference.

    Another way to do it is without streams:

    Map<String, Integer> studentMap = new LinkedHashMap<>();
    studentList.forEach(s -> studentMap.merge(
                             s.getStudentName().toLowerCase(),
                             s.getMarks(),
                             Integer::sum));
    

    This iterates the list of students and uses the Map.merge method to group them by name, summing their marks.

    0 讨论(0)
  • 2021-01-12 17:07

    You can use Collectors.groupingBy(classifier,mapFactory,downstream) method for this purpose:

    List<Student> list = List.of(
            new Student("abc", 30),
            new Student("Abc", 32),
            new Student("ABC", 35),
            new Student("DEF", 40));
    
    Map<String, Integer> map = list.stream()
            .collect(Collectors.groupingBy(
                    Student::getStudentName,
                    () -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER),
                    Collectors.summingInt(Student::getMarks)));
    
    System.out.println(map); // {abc=97, DEF=40}
    
    0 讨论(0)
  • 2021-01-12 17:08

    An alternative solution is to use groupingBy with summingInt:

    Map<String, Integer> studentMap = studentList.stream()
            .collect(Collectors.groupingBy(
                    s -> s.getStudentName().toLowerCase(),
                    Collectors.summingInt(Student::getMarks)));
    
    0 讨论(0)
提交回复
热议问题