【问题标题】:Java getting the average of some elements in an ArraylistJava 获取 Arraylist 中某些元素的平均值
【发布时间】:2021-03-12 19:21:48
【问题描述】:

我是 Java 新手,我正在编写一个程序来管理学生、他们的科目和该科目的成绩。

代码询问学生的详细信息,然后将所有信息保存到 Arraylist。我想求一门学科的平均成绩,但没有成功,我已经计算了某个学生的平均成绩,但是得到某个学科的所有成绩,然后计算平均成绩超出了我的理解范围。

这是我用于创建 Arraylist 的代码:

public class options {

public String name;

public ArrayList<students> studentlist = new ArrayList<students>(10);  

    public String createstudent(String name, String subject, Float rade1, Float grade2, Float grade3) {
        studentlist.add(new students(name, subject, grade1, grade2, grade3);
        return "The student has been added to the database. ";
    }
}

这是学生类的代码:

public class students{
    
    public String name;
    public String subject;
    public Float grade1;  
    public Float grade2;  
    public Float grade3;
    
   public students(String name, String subject, Float grade1, Float grade2, Float grade3) {
        
        this.name= name;
        this.subject= subject;
        this.grade1= grade1;
        this.grade2= grade2;
        this.grade3= grade3;
    }
}   

我尝试过类似的东西

public double getAverageValue(){
  double averageValue = 0;
  double sum = 0;

  if(studentlist.size() > 0){
    for ( int i=0; i < studentlist.size() ; i++) {
      sum += studentlist.get(i).getname().getgrade1().getgrade2().getgrade3();
    }
    averageValue = (sum / (double)studentlist.size())
  }

  return averageValue;
}

但是我不知道如何只选择某个学科的成绩,而不是所有学生的所有成绩,所以我有点卡住了。

编辑:

根据这里的答案和我已经完成的一些工作,这是最终代码:

public String showAverageGrade(String clase){
        int countstudents =0;
        double studentaverage =0;

        for(int i=0 ; i < studentlist.size();i++){
            if(studentlist.get(i).asksubject().equals(subject)){
                studentaverage +=studentlist.get(i).studentaverage ();
                countstudents++;

            }
        }
        return "The average grade of " + subject + " is " + (studentaverage / countstudents) + ".";

    }  

英语不是我的母语,所以任何错误都是因为我翻译了它。

感谢大家的反馈。

【问题讨论】:

  • 如果 Student 的每个实例都可以有一个方法来返回他们的成绩总和以及他们有多少成绩之一,并且简单地/他们并给出你想要的输出,这可能会更好......而且你打破了 Java 代码约定类名应该以大写字母开头,并将其命名为 Student 而不是 Students。
  • 如果你想得到某个科目的成绩,你需要有一个接受该科目的方法,并进行比较。不相关,但 students 类应使用标准 Java 命名约定命名,并且由于它代表单个学生,因此应为单数 Student。

标签: java arraylist average


【解决方案1】:

构建这个的正确方法是首先,您需要将 Student 抽象为一个类。 简单的方法是在主类中创建一个数组属性students,在Student类中它会有一个名为subjects的属性Map来放置一个键(Subject name)和值(Grade)。

如果我理解正确,您需要将一些学生放在主数组中,即他们的成绩,然后计算每个科目所有这些学生的平均值,要计算这一点,您需要创建另一个地图并通过键(主题)总和进行交互所有出现,然后除以计数。

以简单的方式你已经知道所有的主题类型,如果你不知道,它会更复杂,在计算之前你需要另一个没有重复类型的列表来过滤和交互,也许创建这个没有重复的新列表的方法是在这里解释:https://www.baeldung.com/java-remove-duplicates-from-list。

【讨论】:

  • 我有一个选项类,其他的学生和主要,按照你说的做了,并在getaveragevalue中调用了那个方法,它有效,谢谢!
【解决方案2】:

你的方式

使用您的代码,您按职位划分的三个等级中的每一个都可能代表三个不同的课程。我假设您将“法语”课程的所有成绩放在grade1 字段中,将“作文”课程的成绩放在grade2 字段中,将“数学”课程的成绩放在grade3 中。

所以循环学生,分别拉出每个成绩。

float frenchPoints = 0 ;
float compositionPoints = 0 ;
float mathPoints = 0 ;
for( Student student : students )
{
    frenchPoints = ( frenchPoints + student.getGrade1() ) ;
    compositionPoints = ( compositionPoints + student.getGrade2() ) ;
    mathPoints = ( mathPoints + student.getGrade3() ) ;
}

用分数除以分数来取平均值。

如果您想要float 结果,请不要将float(小数)除以int(整数)。因此,在进行除法之前,我们必须将 int 转换为 float。

float frenchAverage = ( frenchPoints / (float) students.size() ) ;
…

我的方式

正如Answer by Bruno Souza Picinini 中所建议的那样,在更现实的情况下,您可以将数据分解为单独的类。您可能会在一个类中表示Student,而该类又可能包含CourseGrade 类的对象集合。

在 Java 16 中,我们可以使用新的 records 特性来简单地编写一个类,其主要目的是透明且不可变地传递数据。编译器隐式创建构造函数、getter、equals & hashCode 和 toString。

public record CourseGrade(String courseName , YearMonth term , Float grade) {}
public record Student(UUID id , String name , Set < CourseGrade > courseGrades) {}

让我们获取一些示例数据。

private List < Student > fetchStudents ( )
{
    List < Student > students =
            List.of(
                    new Student( UUID.fromString( "57ce6790-5094-480c-88f5-79ee9e59b9bb" ) , "Alice" ,
                            Set.of(
                                    new CourseGrade( "French" , YearMonth.of( 2021 , Month.JANUARY ) , 3.2F ) ,
                                    new CourseGrade( "French" , YearMonth.of( 2021 , Month.APRIL ) , 3.6F ) ,
                                    new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.JANUARY ) , 3.3F ) ,
                                    new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.APRIL ) , 3.7F )
                            )
                    ) ,
                    new Student( UUID.fromString( "3ed40f58-fb82-44f0-9ae8-7cc1b317085e" ) , "Bob" ,
                            Set.of(
                                    new CourseGrade( "French" , YearMonth.of( 2021 , Month.JANUARY ) , 2.7F ) ,
                                    new CourseGrade( "French" , YearMonth.of( 2021 , Month.APRIL ) , 2.6F ) ,
                                    new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.JANUARY ) , 2.9F ) ,
                                    new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.APRIL ) , 2.7F )
                            )
                    ) ,
                    new Student( UUID.fromString( "9058567e-8a5e-4606-81b0-1def2bb8ceb5" ) , "Carol" ,
                            Set.of(
                                    new CourseGrade( "French" , YearMonth.of( 2021 , Month.JANUARY ) , 3.0F ) ,
                                    new CourseGrade( "French" , YearMonth.of( 2021 , Month.APRIL ) , 3.1F ) ,
                                    new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.JANUARY ) , 3.2F ) ,
                                    new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.APRIL ) , 3.4F )
                            )
                    )
            );
    return students;
}

编写一个方法来报告特定学期特定课程名称的平均成绩。

我们报告Optional,因为我们可能会在没有提供此类课程的学期中要求课程。因此,如果没有上课,则没有学生获得任何成绩。因此,我们不想报告一个数字,而是要报告一个空的Optional 对象。如果该学期提供的课程有学生注册,那么我们返回一个 Optional,其中包含一个 Float 对象,用于表示平均成绩。

对了,注意浮点类型如float/Floattrade away inaccuracy for speed的执行。如果您关心准确性,请改用BigDecimal 类。

private Optional < Float > reportAverageGradePerCourseInTerm ( String courseName , YearMonth term )
{
    Objects.requireNonNull( courseName );
    Objects.requireNonNull( term );
    List < CourseGrade > courseGrades = new ArrayList <>( this.students.size() );
    for ( Student student : this.students )
    {
        for ( CourseGrade courseGrade : student.courseGrades() )
        {
            if ( courseGrade.courseName().equals( courseName ) && courseGrade.term().equals( term ) )
            {
                courseGrades.add( courseGrade ); // If a match on name and term, remember this `CourseGrade` object. Else, forget/skip.
            }
        }
    }
    if ( courseGrades.size() == 0 ) { return Optional.empty(); }
    float totalPoints = 0F;
    for ( CourseGrade courseGrade : courseGrades )
    {
        totalPoints = totalPoints + courseGrade.grade();
    }
    Float average = ( totalPoints / ( float ) courseGrades.size() );
    return Optional.of( average );
}

使用main 方法将所有代码拉入类App 以驱动演示。

package work.basil.example.reportcard;

import java.time.Month;
import java.time.YearMonth;
import java.util.*;

public class App
{
    public static void main ( String[] args )
    {
        App app = new App();
        app.students = app.fetchStudents();
        System.out.println( "app.students = " + app.students );
        Optional < Float > averageForFrenchIn2021_01 = app.reportAverageGradePerCourseInTerm( "French" , YearMonth.of( 2021 , Month.JANUARY ) );
        System.out.println( "averageForFrenchIn2021_01 = " + averageForFrenchIn2021_01 );
    }

    // Member fields
    List < Student > students;

    // Logic

    private List < Student > fetchStudents ( )
    {
        List < Student > students =
                List.of(
                        new Student( UUID.fromString( "57ce6790-5094-480c-88f5-79ee9e59b9bb" ) , "Alice" ,
                                Set.of(
                                        new CourseGrade( "French" , YearMonth.of( 2021 , Month.JANUARY ) , 3.2F ) ,
                                        new CourseGrade( "French" , YearMonth.of( 2021 , Month.APRIL ) , 3.6F ) ,
                                        new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.JANUARY ) , 3.3F ) ,
                                        new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.APRIL ) , 3.7F )
                                )
                        ) ,
                        new Student( UUID.fromString( "57ce6790-5094-480c-88f5-79ee9e59b9bb" ) , "Bob" ,
                                Set.of(
                                        new CourseGrade( "French" , YearMonth.of( 2021 , Month.JANUARY ) , 2.7F ) ,
                                        new CourseGrade( "French" , YearMonth.of( 2021 , Month.APRIL ) , 2.6F ) ,
                                        new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.JANUARY ) , 2.9F ) ,
                                        new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.APRIL ) , 2.7F )
                                )
                        ) ,
                        new Student( UUID.fromString( "57ce6790-5094-480c-88f5-79ee9e59b9bb" ) , "Carol" ,
                                Set.of(
                                        new CourseGrade( "French" , YearMonth.of( 2021 , Month.JANUARY ) , 3.0F ) ,
                                        new CourseGrade( "French" , YearMonth.of( 2021 , Month.APRIL ) , 3.1F ) ,
                                        new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.JANUARY ) , 3.2F ) ,
                                        new CourseGrade( "Composition" , YearMonth.of( 2021 , Month.APRIL ) , 3.4F )
                                )
                        )
                );
        return students;
    }

    private Optional < Float > reportAverageGradePerCourseInTerm ( String courseName , YearMonth term )
    {
        Objects.requireNonNull( courseName );
        Objects.requireNonNull( term );
        List < CourseGrade > courseGrades = new ArrayList <>( this.students.size() );
        for ( Student student : this.students )
        {
            for ( CourseGrade courseGrade : student.courseGrades() )
            {
                if ( courseGrade.courseName().equals( courseName ) && courseGrade.term().equals( term ) )
                {
                    courseGrades.add( courseGrade ); // If a match on name and term, remember this `CourseGrade` object. Else, forget/skip.
                }
            }
        }
        if ( courseGrades.size() == 0 ) { return Optional.empty(); }
        float totalPoints = 0F;
        for ( CourseGrade courseGrade : courseGrades )
        {
            totalPoints = totalPoints + courseGrade.grade();
        }
        Float average = ( totalPoints / ( float ) courseGrades.size() );
        return Optional.of( average );
    }
}

当main 运行时。

app.students = [Student[id=57ce6790-5094-480c-88f5-79ee9e59b9bb, name=Alice, courseGrades=[CourseGrade[courseName=French, term=2021-04, grade=3.6], CourseGrade[courseName=French, term=2021-01, grade=3.2], CourseGrade[courseName=Composition, term=2021-01, grade=3.3], CourseGrade[courseName=Composition, term=2021-04, grade=3.7]]], Student[id=57ce6790-5094-480c-88f5-79ee9e59b9bb, name=Bob, courseGrades=[CourseGrade[courseName=French, term=2021-04, grade=2.6], CourseGrade[courseName=French, term=2021-01, grade=2.7], CourseGrade[courseName=Composition, term=2021-01, grade=2.9], CourseGrade[courseName=Composition, term=2021-04, grade=2.7]]], Student[id=57ce6790-5094-480c-88f5-79ee9e59b9bb, name=Carol, courseGrades=[CourseGrade[courseName=French, term=2021-04, grade=3.1], CourseGrade[courseName=Composition, term=2021-01, grade=3.2], CourseGrade[courseName=Composition, term=2021-04, grade=3.4], CourseGrade[courseName=French, term=2021-01, grade=3.0]]]]
averageForFrenchIn2021_01 = Optional[2.9666665]

看起来是对的,( 3.2 , 2.7 , 3.0 ) 的平均值是 2.96...。

【讨论】:

    【解决方案3】:

    这些解决方案使您能够为每个学生在每个科目中输入成绩,然后输出所有科目评分的平均值。

    将每个类作为自己的文件添加到您的文件夹中。

    我们用 SchoolSubject.java 表示一个主题:

    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    //abstract class. is init from sub classes
    public abstract class SchoolSubjects {
    
    //grades in a subject
    protected List<Grade> studentGrades;
    Scanner myInput = new Scanner(System.in);
    
    abstract double getAverageValue();
    
    abstract void gradeStudents(List<Student> students) throws IOException;
    
    public SchoolSubjects() {
        this.studentGrades = new ArrayList<>();
    }
    }
    

    然后我们为每个主题创建一个类:

    import java.io.IOException;
    import java.util.List;
    
    public class EnglishSubject extends SchoolSubjects {
    
    //constructor
    public EnglishSubject() {
        super();
    }
    
    //Overrides method in super class
    @Override
    double getAverageValue() {
        double sum = 0;
        if (!studentGrades.isEmpty()) {
            for (Grade grade : studentGrades) {
    
                sum += grade.getGrade();
            }
            return sum / studentGrades.size();
        }
        return sum;
    }
    
    
    //Overrides method in super class
    //parameter: List of students to be graded.
    //Takes console input for grade.
    //generates random name to represent student
    @Override
    void gradeStudents(List<Student> students) throws IOException {
        System.out.println("Grade for english subject");
        for (Student student : students) {
            System.out.print("Student:" + " " + RandomNames.randomIdentifier() + " " + 
    "Enter grade: ");
            double grade = myInput.nextDouble();
            studentGrades.add(new Grade(grade, student));
        }
    }
    }
    

    另一个使用相同方法的主题。请记住,由于继承,每个主题中的方法都可以更改:

    import java.io.IOException;
    import java.util.List;
    
    public class MathSubject extends SchoolSubjects {
    
    //constructor
    public MathSubject() {
        super();
    }
    
    //Overrides method in super class
    @Override
    double getAverageValue() {
        double sum = 0;
        if (!studentGrades.isEmpty()) {
            for (Grade grade : studentGrades) {
    
                sum += grade.getGrade();
            }
            return sum / studentGrades.size();
        }
        return sum;
    }
    
    //Overrides method in super class
    //parameter: List of students to be graded.
    //Takes console input for grade.
    //generates random name to represent student
    @Override
    void gradeStudents(List<Student> students) throws IOException {
        System.out.println("Grade for math subject");
        for (Student student : students) {
            System.out.print("Student:" + " " + RandomNames.randomIdentifier() + " " + 
    "Enter grade: ");
            double grade = myInput.nextDouble();
            studentGrades.add(new Grade(grade, student));
        }
    }
    }
    

    用于学科课程的年级。

    public class Grade {
    //has a grade, and a student object
    private double grade;
    public Student student;
    
    public double getGrade() {
        return grade;
    }
    
    public Grade(double grade, Student student) {
        this.grade = grade;
        this.student = student;
    }
    }
    

    学生班:

    public class Student {
    
    }
    

    您的应用程序。你运行这个文件。

    public class App {
    public static void main(String[] args) throws Exception {
     
        //School
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student());
        studentList.add(new Student());
        studentList.add(new Student());
    
    
        SchoolSubjects mathSubject = new MathSubject();
        SchoolSubjects englishSubject = new EnglishSubject();
    
        mathSubject.gradeStudents(studentList);
        englishSubject.gradeStudents(studentList);
    
        System.out.println("Average grade math:" + " " + mathSubject.getAverageValue());
        System.out.println("Average grade english:" + " " + 
    englishSubject.getAverageValue());
    }
    }
    

    生成随机名称的类:

    import java.util.HashSet;
    import java.util.Set;
    
    public class RandomNames {
    // class variable
    final static String lexicon = "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345674890";
    
    //final java.util.Random rand = new java.util.Random();
    
    // consider using a Map<String,Boolean> to say whether the identifier is being used 
    or not
    final static Set<String> identifiers = new HashSet<String>();
    
    public static String randomIdentifier() {
        StringBuilder builder = new StringBuilder();
        while (builder.toString().length() == 0) {
            int length = new java.util.Random().nextInt(5) + 5;
            for (int i = 0; i < length; i++) {
                builder.append(lexicon.charAt(new 
    java.util.Random().nextInt(lexicon.length())));
            }
            if (identifiers.contains(builder.toString())) {
                builder = new StringBuilder();
            }
        }
        return builder.toString();
    }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-11-30
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-09
      • 2022-06-23
      相关资源
      最近更新 更多