英文:
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 -> 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;
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 -> e.getRating().containsKey(subject))
.mapToInt(e -> 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<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);
}
}
Output:
English=90.5
Chemistry=92.0
French=91.0
Math=82.75
Physics=83.0
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论