计算流中Map的值的总和。

huangapple go评论67阅读模式
英文:

Calculate the sum of values in a Map from Stream Api

问题

我是一个完全的新手,所以我请你不要说脏话)

有一个集合(ArrayList),其中包含了类Student的对象(<HashMap <Subject, Integer> 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() - 返回一个<Subject, Integer>的HashMap,其中包含项目和其评分的列表。
但显然我得到了错误的结果。

英文:

I'm a completely newbie, so I ask you not to swear too much)

There is a collection (ArrayList) that keeps objects of the class Student (<HashMap <Subject, Integer> rating, String name>). I must calculate the average score for a particular subject using the Stream API. I Tried to do it like this:

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

where
sumOnSubjectInGroup is the sum of all students' subject scores.
countMarkInGroup - the number of such marks.
studentsInGroup is a collection with all Student objects.
getRating () - returns a HashMap <Subject, Integer> with a list of items and ratings for it.
But obviously I got the wrong result

答案1

得分: 5

你可以使用.average()来计算平均值,并使用containsKey来检查映射中的存在以进行过滤并获取分数。

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

You can use .average() to calculate average and use containsKey to check existence in the map to filter and get the score.

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

答案2

得分: 2

你可以使用Collectors.averagingInt来计算每个科目的平均值,无需分别计算总和和数量。

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
英文:

You may use Collectors.averagingInt to calculate the average value without separate calculation of sum and count by subject.

import java.util.*;
import java.util.stream.*;

class Student {
    String name;
    Map&lt;String, Integer&gt; rating;
    
    public Student(String name, Map&lt;String, Integer&gt; grades) {
        this.name = name;
        this.rating = grades;
    }
    
    public String getName() { return name; }
    public Map&lt;String, Integer&gt; getRating() { return rating; }
}

public class Main {
    public static void main(String args[]) {
        List&lt;Student&gt; students = Arrays.asList(
            new Student(&quot;John&quot;, Map.of(&quot;Math&quot;, 90, &quot;Physics&quot;, 94, &quot;Chemistry&quot;, 93, &quot;English&quot;, 92)),
            new Student(&quot;Jack&quot;, Map.of(&quot;Math&quot;, 73, &quot;Physics&quot;, 76, &quot;English&quot;, 89)),
            new Student(&quot;Jane&quot;, Map.of(&quot;Math&quot;, 87, &quot;Chemistry&quot;, 91, &quot;French&quot;, 94)),
            new Student(&quot;Joel&quot;, Map.of(&quot;Math&quot;, 81, &quot;Physics&quot;, 79, &quot;French&quot;, 88))
        );
        students
            .stream()
            .flatMap(s -&gt; s.getRating().entrySet().stream())
            .collect(Collectors.groupingBy(
                Map.Entry::getKey, Collectors.averagingInt(Map.Entry::getValue)))
            .entrySet()
            .forEach(System.out::println);
    }
}

Output:

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

huangapple
  • 本文由 发表于 2020年8月29日 02:24:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/63639095.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定