【问题标题】:Calculate the sum of values in a Map from Stream Api从 Stream Api 计算 Map 中的值的总和
【发布时间】:2020-12-17 16:49:52
【问题描述】:

我是个新手,所以我请你不要骂太多)

有一个集合(ArrayList)保存学生类的对象( rating, String name>)。我必须使用 Stream API 计算特定主题的平均分数。我试着这样做:

 sumOnSubjectInGroup = studentsInGroup.stream()
        .filter(e -> e.getRating().entrySet().iterator().next().getKey().equals(subject))
        .mapToInt(e -> e.getRating().entrySet().iterator().next().getValue())
        .reduce(0, (x, y) -> x + y);
 countMarkInGroup = (int) studentsInGroup.stream()
        .filter(e -> e.getRating().entrySet().iterator().next().getKey().equals(subject))
        .count();
 return (double) sumOnSubjectInGroup / countMarkInGroup;

在哪里 sumOnSubjectInGroup 是所有学生科目成绩的总和。 countMarkInGroup - 此类标记的数量。 studentsInGroup 是一个包含所有 Student 对象的集合。 getRating () - 返回一个 HashMap 及其项目列表和评级。 但显然我得到了错误的结果

【问题讨论】:

    标签: java java-stream


    【解决方案1】:

    您可以使用.average()计算平均值并使用containsKey检查地图中是否存在过滤并获得分数。

    Double average = studentsInGroup.stream()
                .filter(e -> e.getRating().containsKey(subject))
                .mapToInt(e -> e.getRating().get(subject))
                .average()
                .orElse(0.0);
    

    【讨论】:

    • 但由于某种原因,这不适用于更复杂的结构。 ArrayList - Arraylist - 学生( rating, String name>)。 prnt.sc/u7pck4 我得到的结果不正确。
    • @robert0801 你需要flatMap 而不是mapArrayList<Student> 变成Student.flatMap(g -> g.getStudentsInGroup.stream()) 一样
    【解决方案2】:

    您可以使用Collectors.averagingInt计算平均值,而无需单独计算sum和count by subject。

    import java.util.*;
    import java.util.stream.*;
    
    class Student {
        String name;
        Map<String, Integer> rating;
        
        public Student(String name, Map<String, Integer> grades) {
            this.name = name;
            this.rating = grades;
        }
        
        public String getName() { return name; }
        public Map<String, Integer> getRating() { return rating; }
    }
    
    public class Main {
        public static void main(String args[]) {
            List<Student> students = Arrays.asList(
                new Student("John", Map.of("Math", 90, "Physics", 94, "Chemistry", 93, "English", 92)),
                new Student("Jack", Map.of("Math", 73, "Physics", 76, "English", 89)),
                new Student("Jane", Map.of("Math", 87, "Chemistry", 91, "French", 94)),
                new Student("Joel", Map.of("Math", 81, "Physics", 79, "French", 88))
            );
            students
                .stream()
                .flatMap(s -> s.getRating().entrySet().stream())
                .collect(Collectors.groupingBy(
                    Map.Entry::getKey, Collectors.averagingInt(Map.Entry::getValue)))
                .entrySet()
                .forEach(System.out::println);
        }
    }
    

    输出:

    English=90.5
    Chemistry=92.0
    French=91.0
    Math=82.75
    Physics=83.0
    

    【讨论】:

      猜你喜欢
      • 2020-01-30
      • 1970-01-01
      • 2018-07-24
      • 1970-01-01
      • 1970-01-01
      • 2022-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多