Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java]如何按科目计算平均分数(使用ArrayList)_Java_Arraylist - Fatal编程技术网

Java]如何按科目计算平均分数(使用ArrayList)

Java]如何按科目计算平均分数(使用ArrayList),java,arraylist,Java,Arraylist,我想知道是否有一种方法可以根据科目而不是学生来计算总分和平均分!。仅供参考,我在学习ArrayList时编写了此代码 这是我正在研究的代码。我想得到的结果是mathTotal:180,korTotal:150,engTotal:90&mathAvg:90,korAvg:75,engAvg:90 公共课科目{ 私有字符串subjectName; 个人智力得分; 公共主题字符串主题名称,整数分数{ this.subjectName=subjectName; 这个分数=分数; } 公共字符串getSu

我想知道是否有一种方法可以根据科目而不是学生来计算总分和平均分!。仅供参考,我在学习ArrayList时编写了此代码

这是我正在研究的代码。我想得到的结果是mathTotal:180,korTotal:150,engTotal:90&mathAvg:90,korAvg:75,engAvg:90

公共课科目{ 私有字符串subjectName; 个人智力得分; 公共主题字符串主题名称,整数分数{ this.subjectName=subjectName; 这个分数=分数; } 公共字符串getSubName{ 返回subjectName; } 公共整数getScore{ 返回分数; } } 导入java.util.ArrayList; 公立班学生{ 私立国际学生; 私有字符串studentName; ArrayList主题列表; public studentent studentID,字符串studentName{ this.studentID=studentID; this.studentName=studentName; subjectList=新的ArrayList; } public void addSubjectString subjectName,整数分数{ 科目=新科目科目名称、分数; subjectList.addsubject; } 公共垃圾堆{ int-total=0; 双亚群=0; System.out.println<+studentName+”的分数>; 对于主题:主题列表{ 合计+=subject.getScore; System.out.printlsubject.getSubName+:+subject.getScore; subCnt++; } 双倍平均值=总/次平均值; String averageCut=String.format%.2f,average; System.out.printlntottal:+total; System.out.printlnaverage:+averageCut; } } 公开课学生测验{ 公共静态无效字符串[]args{ 学生1=新学生1001,艾米·帕克; 学生2=新生1005,Steven Yeun; 学生1.addSubjectMath,80; 学生1.AddSubject韩语,90; 学生2.addSubjectMath,100; 学生2.5名,韩语,60岁; 学生2.addSubjectEnglish,90; 学生1.calcScore; 学生2.calcScore; } } 因为每个学生都有一个科目列表,所以在学生课堂上你无法获得科目的平均分数。一种可能是为科目列表定义一个访问器方法,即StudentgetSubjects,并在学生课堂之外使用该方法按科目计算统计数据。你也可以用地图按主题记录你的总数和计数

例如:

Map<String, Integer> gradeTotalsBySubject = new HashMap<>();
Map<String, Integer> countsBySubject = new HashMap<>();
for (student : students) {
    for (subject : student.getSubjects()) {
        int currentGradeTotal = gradeTotalsBySubject.getOrDefault(subject.getName(), 0);
        currentGradeTotal += subject.getScore();
        gradeTotalsBySubject.put(subject.getName(), current);
        int currentCount = countsBySubject.getOrDefault(subject.getName(), 0);
        currentCount++;
        countsBySubject.put(subject.getName(), currentCount);
    }
}
这将为您提供所需的总数,以及要除以的数字,并按主题分组。此时,您可以迭代gradeTotalsBySubject中的映射条目,并将每个值除以相应计数映射中的计数,即可得到平均值。

您可以在Subject类中添加静态哈希映射。每次你添加一个新的主题时,你必须将主题作为一个键添加到HashMap中,而as值将是一个ArrayList,它将包含你添加的每个分数

科目类别:


如果您可以在学生课堂中为主题列表添加getter/setter,则以下代码适用于您:

public class StudentTest {
    public static void main(String[] args) {

        Student student1 = new Student(1001, "Amy Park");
        Student student2 = new Student(1005, "Steven Yeun");

        student1.addSubject("Math", 80);
        student1.addSubject("Korean", 90);

        student2.addSubject("Math", 100);
        student2.addSubject("Korean", 60);
        student2.addSubject("English", 90);

        List<Student> students =new ArrayList<>();
        students.add(student1);
        students.add(student2);

        List<Subject> subjectList = students.stream()
                .flatMap(student -> student.getSubjectList().stream())
                .collect(Collectors.toList());

        Collector<Subject, ?, Double> avgScoreCollector = Collectors.averagingInt(Subject::getScore);
        Collector<Subject, ?, Integer> totalScoreCollector = Collectors.summingInt(Subject::getScore);
        Map<String, Integer> groupedSubjectsSum =
                subjectList.stream().collect(Collectors.groupingBy(Subject::getSubName, totalScoreCollector));
        Map<String, Double> groupedSubjectsAvg =
                subjectList.stream().collect(Collectors.groupingBy(Subject::getSubName, avgScoreCollector));

        for (Map.Entry<String, Integer> entry : groupedSubjectsSum.entrySet()) {
            System.out.println("Sum of " + entry.getKey() + ":" + entry.getValue());
        }
        System.out.println("\n*************************\n");
        for (Map.Entry<String, Double> entry : groupedSubjectsAvg.entrySet()) {
            System.out.println("Avg of " + entry.getKey() + ":" + entry.getValue());
        }
    }
}

在这个解决方案中,我们将所有主题列表合并在一起,形成一个列表,然后对其执行avg和sum函数。使用java8 lambda提供了更好的修改和维护灵活性。

如前面的答案所述,为了获得每个主题的统计数据,可以向主题类添加一个静态地图来存储分数,并方便计算总分数和平均分数

然而,由于Java8,有一个类可以有效地与流API一起使用,通过使用

例如,方法Student::calcScore可以修改为使用此类,如下所示:

公共垃圾堆{ System.out.printf<%s的分数>%n,学生姓名; IntSummaryStatistics=subjectList.stream//stream //在收集统计数据时打印每个主题 .peek主题->系统输出打印F%-10s:\t%4d%n, subject.getSubjectName,subject.getScore .collectCollectors.SummaringIntsObject::getScore; //打印统计数据 System.out.println-.repeat12+studentName.length; System.out.printf%-10s:\t%4d%n,总计,stats.getSum; System.out.printf%-10s:\t%7.2f%n,AVERAGE,stats.getAverage; System.out.println=.repeat12+studentName.length; } 课程主题可更新如下,以利用IntSummaryStatistics:

公共课科目{ 私有字符串subjectName; 个人智力得分; 私有静态映射rawScoresBySubject=新树映射; 公共主题字符串主题名称,整数分数{ this.subjectName=subjectName; 这个分数=分数; rawScoresBySubject .ComputeFabSentSubjectName,键->新建阵列列表 .addscore; } 公共静态映射getStats{ 返回rawScoresBySubject.entrySet.stream//stream .toMap Map.Entry::getKey, e->e.getValue.stream//stream .CollectCollector.SummaringInTinteger::intValue ; } //能手/二传手 } 这里,树映射用于按subjectName进行排序。此外,映射使用ComputeFabSent方法填充,该方法允许添加初始值。在本例中,它是一个空的ArrayList,并通过添加分数立即使用该值

测试:

公共静态无效字符串[]args{ 学生1=新学生1001,艾米·帕克; 学生2=新生1005,Steven Yeun; 学生1.addSubjectMath,80; 学生1.AddSubject韩语,90; 学生2.addSubjectMath,100; 学生2.5名,韩语,60岁; 学生2.addSubjectEnglish,90; 学生1.calcScore; 学生2.calcScore; Subject.getStats .forEachsubject,统计信息-> System.out.printf%-10s:\t%7.2f\t%4d/%d%n, 主题,stats.getAverage,stats.getSum,stats.getCount ; } 输出:

Sum of English:90
Sum of Korean:150
Sum of Math:180

*************************

Avg of English:90.0
Avg of Korean:75.0
Avg of Math:90.0
< Amy Park's score >
Math      :   80
Korean    :   90
--------------------
TOTAL     :  170
AVERAGE   :   85.00
====================
< Steven Yeun's score >
Math      :  100
Korean    :   60
English   :   90
-----------------------
TOTAL     :  250
AVERAGE   :   83.33
=======================
English   :   90.00   90 / 1
Korean    :   75.00  150 / 2
Math      :   90.00  180 / 2

我认为首先你必须修改你的设计。我提议添加学校抽象,以保存学生名单和计算:

公立期末班学校{ 私人最终名单学生=新ArrayList; 公共无效添加学生学生{ students.addstudent; } 公开学生名单{ 返回Collections.unmodifiableListstudents; } 公共地图calcAverageScoreBySubject{ Map Map=新的HashMap; getScoresBySubject.forEachsubjectName,分数-> map.putsubjectName,scores.stream .mapToDoubleInteger::doubleValue .平均0.0; 返回图; } 公共地图calcTotalScoreBySubject{ Map Map=新的HashMap; getScoresBySubject.forEachsubjectName,分数-> map.putsubjectName,scores.stream.mapToInti->i.sum; 返回图; } 私有映射getScoresBySubject{ Map Map=新的HashMap; 学生流 .mapStudent::getSubjects .flatMapList::流 .forEachsubject->{ 如果!map.containsKeysubject.getName map.putsubject.getName,新的ArrayList; map.getsubject.getName.addsubject.score; }; 返回图; } } 然后,您应该为学生和主题使用不可修改的对象:

公共静态期末科目{ 私有最终字符串名; 个人最终积分; 公共主题字符串名称,整数分数{ this.name=名称; 这个分数=分数; } 公共字符串getName{ 返回名称; } 公共整数getScore{ 返回分数; } } 公共期末班学生{ 私有最终int id; 私有最终字符串名; 私有最终列表主题=新ArrayList; 公共学生id,字符串名称{ this.id=id; this.name=名称; } 公共整数getId{ 返回id; } 公共字符串getName{ 返回名称; } 公共无效添加主题主题{ subjects.addsubject; } 公共主题列表{ 返回Collections.unmodifiableListsubjects; } } 最后,您的测试可以如下所示:

public class StudentTest {
public static void main(String[] args) {
    
    Student student1 = new Student(1001, "Amy Park");
    Student student2 = new Student(1005, "Steven Yeun");
    
    student1.addSubject("Math", 80);
    student1.addSubject("Korean", 90);
    
    student2.addSubject("Math", 100);
    student2.addSubject("Korean", 60);
    student2.addSubject("English", 90);
    
    student1.calcScore();
    student2.calcScore();
    
    Subject.subjectsScores.forEach((k,v)->{
        
        int total=0;
        
        for(int sc : v)
        {
            total+=sc;
        }
        
        int av = total / v.size();
        
        System.out.printf("Subject: %s -- Total: %d -- Average: %d\n",k,total,av);
        
    }); 
   }
}
公开课学生测验{ 公共静态无效字符串…args{ 学校=新学校; school.addStudentamyPark; school.addStudentstevenYeun; 地图主题名称平均得分=school.calacveragescorebysubject; 地图主题名称TotalScore=school.calcTotalScoreBySubject; school.getStudents.forEachstudent->{ System.out.format<%d:%s的核心>\n,student.getId,student.getName; student.getSubjects.forEachsubject->{ 字符串subjectName=subject.getName; int分数=subject.getScore; int total=subjectNameTotalScore.getsubjectName; 双平均=subjectNameAverageScore.getsubjectName; System.out.formatLocale.ENGLISH,%s:%d主题-总计:%d,平均值:%.1f\n,主题名称,分数,总计,平均值; }; System.out.println; }; } 私人静态学生公园{ 学生=新学生1001,艾米·帕克; student.addsubjectnewsubjectmath,80; student.addSubjectnew subject韩语,90; 留学生; } 私人静态学生stevenYeun{ 学生=新生1005,Steven Yeun; student.addsubjectnewsubjectmath,100; student.addSubjectnew subject韩语,60岁; student.addSubjectnew SubjectEnglish,90; 留学生; } } 输出:

Sum of English:90
Sum of Korean:150
Sum of Math:180

*************************

Avg of English:90.0
Avg of Korean:75.0
Avg of Math:90.0
< Amy Park's score >
Math      :   80
Korean    :   90
--------------------
TOTAL     :  170
AVERAGE   :   85.00
====================
< Steven Yeun's score >
Math      :  100
Korean    :   60
English   :   90
-----------------------
TOTAL     :  250
AVERAGE   :   83.33
=======================
English   :   90.00   90 / 1
Korean    :   75.00  150 / 2
Math      :   90.00  180 / 2

非常感谢您的解决方案!
真的帮了我很大的忙。如果你有帮助,你考虑接受一个答案:非常感谢你的详细解决方案!!学习新事物总是一种乐趣;我很高兴能帮助你