0

0

Java嵌套循环中结构化数据收集与处理的最佳实践

DDD

DDD

发布时间:2025-11-14 13:41:01

|

900人浏览过

|

来源于php中文网

原创

Java嵌套循环中结构化数据收集与处理的最佳实践

java中处理嵌套循环内复杂且关联的数据收集时,直接使用分散的数组往往导致数据管理和后续处理的困难。本文将详细介绍如何通过面向对象编程思想,定义自定义类来封装相关数据,从而实现更清晰、更易于维护和扩展的数据结构。通过实例代码,我们将演示如何创建学生对象、收集其各项成绩,并进行简单的输出处理,提升代码的可读性和功能性。

软件开发中,尤其是在需要从用户处收集多组相关数据时,例如一个班级中每个学生的姓名、多门测验成绩、期中和期末成绩等,开发者经常会遇到如何高效、清晰地组织这些数据的问题。如果仅依赖于简单的字符串数组或基本数据类型,当数据结构变得复杂(如嵌套循环中收集不同类型的成绩)时,代码会迅速变得难以管理和维护,尤其是在后续需要对这些数据进行计算或展示时。

传统方法的局限性

考虑以下场景:我们需要为多名学生收集姓名、两次测验成绩、一次期中成绩和一次期末成绩。如果沿用原始代码中在每次外层循环(学生)内部创建新的局部数组来存储测验、期中和期末成绩,会遇到以下问题:

  1. 数据丢失 每次外层循环迭代时,quiz、midterm 和 myfinal 数组都会被重新创建,并且在当前迭代结束后,这些数组所引用的数据就会丢失,无法在循环外部访问。这意味着我们无法收集所有学生的成绩。
  2. 数据分散: 学生的姓名和其对应的各项成绩被存储在不同的、不关联的数组中,使得在需要访问特定学生的完整信息时,需要进行复杂的索引匹配。
  3. 类型不一致: 原始代码中使用 String[] 来存储成绩,这在进行数学计算时需要额外的类型转换,增加了代码的复杂性和出错的可能性。

为了克服这些局限性,最佳实践是采用面向对象的方法来结构化数据。

面向对象的数据结构:定义 Student 类

面向对象编程(OOP)提供了一种优雅的解决方案,即通过定义一个自定义类来封装所有与一个“学生”相关的数据。这个类将作为学生信息的蓝图,每个学生都是这个类的一个实例。

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

Moshi Chat
Moshi Chat

法国AI实验室Kyutai推出的端到端实时多模态AI语音模型,具备听、说、看的能力,不仅可以实时收听,还能进行自然对话。

下载

首先,我们定义一个 Student 类,包含学生的姓名以及各项成绩。为了便于后续的数值计算,成绩应使用 int 或 double 类型存储。

public class Student {
    private String name;
    private int[] quizzes;    // 存储测验成绩
    private int[] midterms;   // 存储期中成绩
    private int[] finals;     // 存储期末成绩

    // 构造函数:用于创建Student对象并初始化其属性
    public Student(String name, int numberOfQuizzes, int numberOfMidterms, int numberOfFinals) {
        this.name = name;
        this.quizzes = new int[numberOfQuizzes];
        this.midterms = new int[numberOfMidterms];
        this.finals = new int[numberOfFinals];
    }

    // Getter 方法:允许外部访问私有属性
    public String getName() {
        return name;
    }

    public int[] getQuizzes() {
        return quizzes;
    }

    public int[] getMidterms() {
        return midterms;
    }

    public int[] getFinals() {
        return finals;
    }

    // Setter 方法:允许外部修改私有属性(如果需要)
    public void setQuizMark(int index, int mark) {
        if (index >= 0 && index < quizzes.length) {
            this.quizzes[index] = mark;
        } else {
            System.out.println("Invalid quiz index.");
        }
    }

    public void setMidtermMark(int index, int mark) {
        if (index >= 0 && index < midterms.length) {
            this.midterms[index] = mark;
        } else {
            System.out.println("Invalid midterm index.");
        }
    }

    public void setFinalMark(int index, int mark) {
        if (index >= 0 && index < finals.length) {
            this.finals[index] = mark;
        } else {
            System.out.println("Invalid final index.");
        }
    }

    // 辅助方法:计算平均测验成绩
    public double getAverageQuizScore() {
        if (quizzes.length == 0) return 0.0;
        int sum = 0;
        for (int mark : quizzes) {
            sum += mark;
        }
        return (double) sum / quizzes.length;
    }

    // 可以添加更多计算方法,例如总分、平均分等
}

重构主程序:数据收集与处理

有了 Student 类,我们就可以重构主程序来高效地收集和处理数据。关键在于创建一个 Student 对象的数组,并在外层循环中为每个学生创建一个 Student 实例,然后将所有相关数据存储到该实例中。

import java.util.Scanner;

public class StudentManagement {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        System.out.println("How many students do you want to enter?");
        int numberOfStudents = 0;
        // 输入验证,确保用户输入的是一个整数
        while (!input.hasNextInt()) {
            System.out.println("Invalid input. Please enter a number.");
            input.next(); // 消费掉无效输入
        }
        numberOfStudents = input.nextInt();
        input.nextLine(); // 消费掉换行符,避免影响后续的nextLine()

        // 定义每个学生需要输入的测验、期中、期末数量
        final int NUM_QUIZZES = 2;
        final int NUM_MIDTERMS = 1;
        final int NUM_FINALS = 1;

        // 创建Student对象数组来存储所有学生的信息
        Student[] students = new Student[numberOfStudents];

        for (int stIndex = 0; stIndex < numberOfStudents; stIndex++) {
            System.out.println("\n--- Entering data for Student " + (stIndex + 1) + " ---");
            System.out.println("Enter the name for student " + (stIndex + 1) + ":");
            String studentName = input.nextLine(); // 读取整行姓名

            // 创建新的Student对象
            students[stIndex] = new Student(studentName, NUM_QUIZZES, NUM_MIDTERMS, NUM_FINALS);

            // 收集测验成绩
            for (int qzIndex = 0; qzIndex < NUM_QUIZZES; qzIndex++) {
                System.out.println("Enter quiz mark " + (qzIndex + 1) + " for " + studentName + ":");
                int quizMark = 0;
                while (!input.hasNextInt()) {
                    System.out.println("Invalid input. Please enter an integer mark.");
                    input.next();
                }
                quizMark = input.nextInt();
                students[stIndex].setQuizMark(qzIndex, quizMark);
            }
            input.nextLine(); // 消费掉数字输入后的换行符

            // 收集期中成绩
            for (int mtIndex = 0; mtIndex < NUM_MIDTERMS; mtIndex++) {
                System.out.println("Enter midterm mark " + (mtIndex + 1) + " for " + studentName + ":");
                int midtermMark = 0;
                while (!input.hasNextInt()) {
                    System.out.println("Invalid input. Please enter an integer mark.");
                    input.next();
                }
                midtermMark = input.nextInt();
                students[stIndex].setMidtermMark(mtIndex, midtermMark);
            }
            input.nextLine(); // 消费掉数字输入后的换行符

            // 收集期末成绩
            for (int fnIndex = 0; fnIndex < NUM_FINALS; fnIndex++) {
                System.out.println("Enter final mark " + (fnIndex + 1) + " for " + studentName + ":");
                int finalMark = 0;
                while (!input.hasNextInt()) {
                    System.out.println("Invalid input. Please enter an integer mark.");
                    input.next();
                }
                finalMark = input.nextInt();
                students[stIndex].setFinalMark(fnIndex, finalMark);
            }
            input.nextLine(); // 消费掉数字输入后的换行符
        }

        input.close();

        // 数据收集完成后,进行处理和展示
        System.out.println("\n--- All Students' Marks ---");
        for (Student student : students) {
            System.out.println("Student Name: " + student.getName());
            System.out.print("  Quizzes: ");
            for (int mark : student.getQuizzes()) {
                System.out.print(mark + " ");
            }
            System.out.println(" (Average: " + String.format("%.2f", student.getAverageQuizScore()) + ")");

            System.out.print("  Midterms: ");
            for (int mark : student.getMidterms()) {
                System.out.print(mark + " ");
            }
            System.out.println();

            System.out.print("  Finals: ");
            for (int mark : student.getFinals()) {
                System.out.print(mark + " ");
            }
            System.out.println();
            System.out.println("---------------------------");
        }
    }
}

注意事项与最佳实践

  1. 数据类型选择: 对于分数等数值数据,应使用 int 或 double 类型,而不是 String。这不仅避免了不必要的类型转换,还确保了数据在存储时的语义正确性。
  2. 输入验证: 在从用户读取输入时,始终进行输入验证。例如,使用 Scanner.hasNextInt() 检查用户是否输入了整数,防止 InputMismatchException。
  3. 消费换行符: 当使用 Scanner.nextInt() 或 Scanner.nextDouble() 等方法读取数字后,Scanner 会将换行符留在输入缓冲区中。如果紧接着使用 Scanner.nextLine() 读取字符串,它会立即读取这个残留的换行符,导致跳过实际的字符串输入。因此,在数字输入后,通常需要调用 input.nextLine() 来消费掉这个换行符。
  4. 封装性 Student 类中的属性(如 name, quizzes)被声明为 private,并通过公共的 getter 和 setter 方法来访问和修改。这遵循了面向对象编程的封装原则,提高了代码的模块化和安全性。
  5. 灵活性: 构造函数允许我们为每个学生指定不同数量的测验、期中和期末成绩,这增加了程序的灵活性。如果需要更动态的数量(例如,学生可以有任意数量的测验),可以考虑使用 ArrayList 而不是固定大小的数组。
  6. 错误处理: 在 setQuizMark 等方法中添加索引边界检查,以防止 ArrayIndexOutOfBoundsException。
  7. 扩展性: 可以在 Student 类中添加更多的方法,例如计算总分、平均分、判断及格与否等,将与学生相关的业务逻辑集中管理,使主程序更简洁。

总结

通过采用面向对象的方法,定义一个 Student 类来封装学生的姓名和各项成绩,我们成功解决了在嵌套循环中收集和管理复杂相关数据的问题。这种方法不仅使数据结构更加清晰、易于理解,而且极大地提高了代码的可维护性、可读性和可扩展性。它将数据与操作数据的方法绑定在一起,是处理复杂数据场景的强大工具

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

825

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

724

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

728

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

395

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

445

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

428

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16861

2023.08.03

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.1万人学习

C# 教程
C# 教程

共94课时 | 5.7万人学习

Java 教程
Java 教程

共578课时 | 40万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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