首页 > Java > java教程 > 正文

Java中对象数组的统计分析:计算平均值与最高分

花韻仙語
发布: 2025-10-12 13:38:55
原创
691人浏览过

Java中对象数组的统计分析:计算平均值与最高分

在Java编程中,我们经常需要处理包含多个自定义对象的数组或集合。这些对象通常封装了多种类型的数据,例如字符串(String)和整数(int)。本教程将以一个学生成绩管理的示例,详细讲解如何从一个学生对象数组中提取并计算特定数值属性(如学生分数)的平均值和最高分。

1. 理解与完善 Student 类

首先,我们需要一个表示学生信息的类。这个 student 类应包含学生的姓名(string)和分数(int)。为了使数据可访问和修改,还需要提供相应的构造器、getter和setter方法。

原始的 Student 类设计:

import java.util.Scanner;

public class Student {

    private String name;
    private int score;

    public Student() {
    }

    public Student(String name, int score){
        this.name = name;
        this.score = score;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public void readInput() {
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Please enter the student's name: ");
        this.name = keyboard.next();
        System.out.println("Please enter the student's score: ");
        this.score = keyboard.nextInt();
    }

    public void writeOutput() {
        System.out.println("The student's name and score: " + name + ", " + score + "%");
    }

    // 原始设计中的Getter方法有误
    // public String getName(String name) {
    //     return this.name;
    // }
    // public int getScore(int score) {
    //     return score;
    // }
}
登录后复制

问题分析与修正: 原始 Student 类中的 getName(String name) 和 getScore(int score) 方法签名不正确。标准的Getter方法不应接受参数,它们的作用是返回私有成员变量的值。

修正后的 Student 类:

import java.util.Scanner; // 确保导入Scanner

public class Student {

    private String name;
    private int score;

    public Student() {
        // 默认构造器,可用于创建空对象
    }

    public Student(String name, int score){
        this.name = name;
        this.score = score;
    }

    // Setter方法
    public void setName(String name) {
        this.name = name;
    }

    public void setScore(int score) {
        this.score = score;
    }

    // Getter方法:不应有参数
    public String getName() { // 修正:移除参数
        return this.name;
    }

    public int getScore() { // 修正:移除参数
        return this.score; // 修正:返回实例变量this.score
    }

    // 从控制台读取学生信息
    public void readInput() {
        Scanner keyboard = new Scanner(System.in); // 每次调用都创建新Scanner可能不是最佳实践,但在此示例中可接受
        System.out.println("Please enter the student's name: ");
        this.name = keyboard.next();
        System.out.println("Please enter the student's score: ");
        this.score = keyboard.nextInt();
        // keyboard.close(); // 在方法内部关闭Scanner可能会导致后续输入问题,通常在程序结束时统一关闭
    }

    // 输出学生信息
    public void writeOutput() {
        System.out.println("The student's name and score: " + name + ", " + score + "%");
    }
}
登录后复制

注意事项: 在实际应用中,Scanner 对象通常在程序的入口点创建一次,并作为参数传递或通过其他方式共享,以避免资源泄露和不必要的对象创建。

2. 实现成绩统计逻辑 (TestReporter 类)

TestReporter 类负责管理学生数组,并计算班级的平均分和最高分。

立即学习Java免费学习笔记(深入)”;

原始的 TestReporter 类设计:

import java.lang.reflect.Array; 
import java.util.Arrays; 
import java.util.Scanner;

public class TestReporter {

    private int highestScore;
    private double averageScore;
    private Student[] ourClass; 
    private int numOfStudents;

    public TestReporter(){
    }

    public void getData() {
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Please enter the number of students");
        numOfStudents = keyboard.nextInt();
        ourClass = new Student[numOfStudents];
        for (int i = 0; i < numOfStudents ; i++) {
            ourClass[i] = new Student(); 
            ourClass[i].readInput();
        }
        // keyboard.close(); // 同Student类,此处关闭Scanner可能导致问题
    }

    public void computeStats() {
        double total = 0;
        for (int i = 0; i < numOfStudents; i++) {
            // 原始代码:total = total + ourClass[i]; // 错误:不能将Student对象直接加到double
        }
        // averageScore = total / ourClass.length; // 原始代码:在循环外计算,但total计算有误
    }

    public void displayResults() {
        for (Student Student: ourClass) {
            Student.writeOutput();
        }
    }
}
登录后复制

问题分析与修正:

美图设计室
美图设计室

5分钟在线高效完成平面设计,AI帮你做设计

美图设计室 29
查看详情 美图设计室
  1. computeStats 方法中的错误:
    • total = total + ourClass[i];:ourClass[i] 是一个 Student 对象,不能直接与 double 类型的 total 相加。正确的做法是调用 ourClass[i].getScore() 获取分数。
    • 没有计算 highestScore 的逻辑。
    • highestScore 和 averageScore 应该更新类的成员变量,而不是在方法内部声明局部变量(除非有特殊需求)。
  2. displayResults 方法的调用顺序: 在显示结果之前,需要确保 computeStats 已经被调用,以更新 highestScore 和 averageScore。

修正后的 TestReporter 类:

import java.util.Scanner; // 仅需导入Scanner,其他可能不需要

public class TestReporter {

    private int highestScore;
    private double averageScore;
    private Student[] ourClass; 
    private int numOfStudents;

    public TestReporter(){
        // 构造器可以进行一些初始化,例如将最高分初始化为0或Integer.MIN_VALUE
        this.highestScore = 0; // 假设分数非负
        this.averageScore = 0.0;
        this.numOfStudents = 0;
    }

    // 获取学生数据
    public void getData() {
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Please enter the number of students:");
        numOfStudents = keyboard.nextInt();
        ourClass = new Student[numOfStudents];
        for (int i = 0; i < numOfStudents ; i++) {
            ourClass[i] = new Student(); 
            System.out.println("\n--- Entering data for Student " + (i + 1) + " ---");
            ourClass[i].readInput();
        }
        // 考虑到readInput内部也创建Scanner,此处不关闭,由系统或更上层管理
    }

    // 计算统计数据:平均分和最高分
    public void computeStats() {
        if (numOfStudents == 0 || ourClass == null) {
            System.out.println("No student data available to compute stats.");
            this.averageScore = 0.0;
            this.highestScore = 0;
            return;
        }

        double total = 0;
        this.highestScore = 0; // 初始化最高分为0,适用于非负分数。若分数可能为负,应初始化为Integer.MIN_VALUE。

        for (int i = 0; i < numOfStudents; i++) {
            int currentScore = ourClass[i].getScore(); // 正确获取学生分数
            total += currentScore; // 累加总分

            if (currentScore > this.highestScore) {
                this.highestScore = currentScore; // 更新最高分
            }
        }
        this.averageScore = total / numOfStudents; // 计算平均分
    }

    // 显示结果
    public void displayResults() {
        // 在显示之前确保统计数据已计算
        computeStats(); 

        System.out.println("\n--- Student Details ---");
        for (Student student : ourClass) { // 使用增强for循环遍历数组
            student.writeOutput();
        }

        System.out.println("\n--- Class Statistics ---");
        System.out.println("Total number of students: " + numOfStudents);
        System.out.println("Average Score = " + String.format("%.2f", this.averageScore)); // 格式化输出平均分
        System.out.println("Highest Score = " + this.highestScore);
    }

    // 主方法,用于运行程序
    public static void main(String[] args) {
        TestReporter reporter = new TestReporter();
        reporter.getData(); // 获取学生数据
        // reporter.computeStats(); // displayResults会调用computeStats,此处可省略
        reporter.displayResults(); // 显示结果
    }
}
登录后复制

3. 完整的示例代码

为了方便读者运行和测试,我们将 Student 类和 TestReporter 类整合,并提供一个 main 方法作为程序的入口。

Student.java

import java.util.Scanner;

public class Student {

    private String name;
    private int score;

    public Student() {
    }

    public Student(String name, int score){
        this.name = name;
        this.score = score;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public String getName() {
        return this.name;
    }

    public int getScore() {
        return this.score;
    }

    public void readInput() {
        Scanner keyboard = new Scanner(System.in); // 注意:实际应用中Scanner的管理
        System.out.print("  Enter student's name: ");
        this.name = keyboard.next();
        System.out.print("  Enter student's score: ");
        this.score = keyboard.nextInt();
        // keyboard.close(); // 不在此处关闭
    }

    public void writeOutput() {
        System.out.println("Name: " + name + ", Score: " + score + "%");
    }
}
登录后复制

TestReporter.java

import java.util.Scanner;

public class TestReporter {

    private int highestScore;
    private double averageScore;
    private Student[] ourClass; 
    private int numOfStudents;

    public TestReporter(){
        this.highestScore = 0; // 初始化为0,假设分数非负
        this.averageScore = 0.0;
        this.numOfStudents = 0;
    }

    public void getData() {
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Please enter the number of students:");
        numOfStudents = keyboard.nextInt();
        ourClass = new Student[numOfStudents];
        for (int i = 0; i < numOfStudents ; i++) {
            ourClass[i] = new Student(); 
            System.out.println("\n--- Entering data for Student " + (i + 1) + " ---");
            ourClass[i].readInput();
        }
        // keyboard.close(); // 不在此处关闭
    }

    public void computeStats() {
        if (numOfStudents == 0 || ourClass == null) {
            System.out.println("No student data available to compute stats.");
            this.averageScore = 0.0;
            this.highestScore = 0;
            return;
        }

        double total = 0;
        this.highestScore = 0; // 重新初始化,确保每次计算都是从头开始

        for (int i = 0; i < numOfStudents; i++) {
            int currentScore = ourClass[i].getScore();
            total += currentScore;

            if (currentScore > this.highestScore) {
                this.highestScore = currentScore;
            }
        }
        this.averageScore = total / numOfStudents;
    }

    public void displayResults() {
        computeStats(); // 确保在显示前计算统计数据

        System.out.println("\n--- Student Details ---");
        for (Student student : ourClass) {
            student.writeOutput();
        }

        System.out.println("\n--- Class Statistics ---");
        System.out.println("Total number of students: " + numOfStudents);
        System.out.println("Average Score = " + String.format("%.2f", this.averageScore));
        System.out.println("Highest Score = " + this.highestScore);
    }

    public static void main(String[] args) {
        TestReporter reporter = new TestReporter();
        reporter.getData();
        reporter.displayResults();
    }
}
登录后复制

4. 注意事项与最佳实践

  1. Getter/Setter 的正确用法: Getter 方法用于获取私有成员变量的值,不应接受参数。Setter 方法用于设置私有成员变量的值,通常接受一个与成员变量类型相同的参数。
  2. 变量初始化: 在计算最大值时,highestScore 应被初始化为一个足够小的值(例如 0 对于非负分数,或 Integer.MIN_VALUE 对于可能包含负数的情况),以确保任何有效分数都能被正确识别为最大值。
  3. 循环遍历对象数组: 使用传统的 for 循环(通过索引)或增强 for 循环(for (Student student : ourClass))都是有效的遍历方式。当需要访问数组索引时,传统 for 循环更合适;当仅需遍历元素时,增强 for 循环更简洁。
  4. 职责分离: TestReporter 类很好地体现了职责分离的原则。getData 负责数据输入,computeStats 负责数据计算,displayResults 负责数据输出。这种模块化设计提高了代码的可读性和可维护性。
  5. Scanner 资源管理: 在实际生产环境中,Scanner 对象应谨慎管理。频繁地创建和关闭 Scanner 可能会导致资源泄露或异常。通常建议在应用程序生命周期中只创建一次,并在程序结束时统一关闭。在本教程示例中,为了简化,readInput 和 getData 方法内部都创建了 Scanner,但在大型应用中应避免。
  6. 错误处理: 对于用户输入,应考虑添加错误处理机制,例如使用 try-catch 块来处理 InputMismatchException,以防止用户输入非数字字符导致程序崩溃。

总结

通过本教程,我们学习了如何在Java中有效地处理包含多种数据类型的对象数组。关键在于正确设计自定义类(如 Student),确保 Getter 和 Setter 方法的规范性,并通过遍历数组来访问对象的特定属性,进而执行统计计算。清晰的模块化设计和对细节(如变量初始化、资源管理)的关注是编写健壮、可维护代码的重要方面。掌握这些技能对于任何需要进行数据处理的Java开发者都至关重要。

以上就是Java中对象数组的统计分析:计算平均值与最高分的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号