南昌航空大学第一次BLOG
序言:
Java是一门跨平台、面向对象的高级编程语言,已经成为现代软件开发领域中不可或缺的一部分。Java的重要性不仅体现在其广泛的应用领域和庞大的开发人员社区,更因为其具有以下几个重要的优点:
首先,Java具有很高的可移植性。Java程序可以在不同的操作系统、硬件平台上运行,这得益于Java虚拟机(JVM)的存在,它作为一个中间层将Java程序转换成本地机器指令。因此,Java可以帮助开发者节省时间和成本,同时提升软件的可移植性和可靠性。
其次,Java是一门多范式语言,即支持面向对象编程、过程式编程和函数式编程等多种编程范式。这使得Java可以适应不同的开发需求和编程风格,同时也让Java成为一个非常灵活的语言。
另外,Java拥有丰富的类库和工具,包括Swing、AWT、JavaFX等图形界面库,以及Apache Struts、Spring等开发框架。这些类库和工具可以帮助开发者更加便捷地实现各种功能,并提高软件的开发效率和质量。
最重要的是,Java具有很高的安全性和可靠性。Java的虚拟机提供了内存管理、线程管理、安全性管理等多种保护机制,可以有效地防止常见的运行时错误和安全漏洞,同时使得Java程序更加稳定和可靠。
总之,Java作为一门跨平台、面向对象、多范式的高级编程语言,拥有可移植性、灵活性、丰富的类库和工具、高安全性和可靠性等多个优点,在现代软件开发领域中扮演着极为重要的角色。
前言:
题量 三次作业题量分别是984。
知识点 类和对象,数组,循环结构,字符串处理,分装和访问控制,基本数据类型和运算符,类型转换,格式化输出。
难度 难度为递进,第一次到第三次作业越来越难。
设计与分析
1.菜单计价题目:
复杂度分析:


类图:

这段代码是一个简单的菜品点餐程序。代码中定义了一个Dish类,表示菜品,包含菜品名称和价格两个属性,以及构造函数和根据份数计算价格的方法。在主函数中创建了一个包含4个菜品的菜单数组。然后通过循环输入菜名和份数,根据输入的菜名在菜单数组中查找对应的菜品,如果存在则计算总价格,如果不存在则输出错误信息。最后打印总价格。
分析整体逻辑,代码的主要功能是实现菜品的点单和价格计算。用户可以通过输入菜名和份数来点餐,程序会根据菜名在菜单中查找对应的菜品,并根据份数计算价格。如果菜名不存在,则输出错误信息。最后程序会输出总价格。
需要注意的是,代码中使用了Scanner类来进行输入操作,用于接收用户的菜名和份数输入。另外,菜品的价格根据不同的份数进行了不同的计算,分别对应不同的折扣策略。
当用户运行该程序时,程序会先创建一个Dish类的对象数组dishes,其中存储了4个菜品的信息。然后,程序通过Scanner类获取用户的输入。用户输入的菜名和份数会被分别保存在dishName和portion变量中。
接下来,程序会循环处理用户的输入。如果用户输入的菜名为"end",则表示点餐结束,程序会跳出循环。否则,程序会遍历菜单数组dishes,查找是否有与用户输入的菜名相匹配的菜品。
如果找到了匹配的菜品,程序将设置一个标志dishExist为true,并调用菜品对象的getPrice方法,传入用户输入的份数portion,计算当前菜品的价格,并累加到总价格totalPrice中。
如果未找到匹配的菜品,程序会输出错误信息,提示该菜品不存在,并继续处理下一个用户输入。
最后,程序输出总价格totalPrice。
2.成绩计算-1-类、数组的基本运用
复杂度分析:


类图:

这段代码是一个学生成绩管理程序。程序首先创建一个Scanner对象input,用于接收用户的输入。接下来,定义了一个包含5个元素的字符串数组studentsInfo,用于保存学生信息。
通过一个循环,程序从用户的输入中获取5行学生信息,并将每行学生信息存储在studentsInfo数组相应位置上。
之后,程序再次使用一个循环遍历studentsInfo数组,对每个学生的信息进行处理。首先,将当前学生信息存储在字符串变量info中,并使用split方法将info按空格分隔为一个字符串数组infoArray。
然后,从infoArray数组中分别提取学生的学号、姓名、语文分数、数学分数和物理分数,并将它们转换为对应的数据类型。接着,创建一个Student对象student,将提取的学生信息作为参数传递给Student类的构造函数进行对象的初始化。
随后,通过调用student的方法,分别获取学生的总分和平均分,并将这些计算结果使用System.out.printf方法格式化输出,依次输出学生的学号、姓名、总分和平均分。
最后,程序结束执行。
这段代码使用了面向对象的思想,将学生的信息和操作封装在了一个Student类中。
Student类有私有属性id、name、chineseScore、mathScore和physicsScore,用于表示学生的学号、姓名、语文分数、数学分数和物理分数。
类中定义了一个构造函数,用于对学生对象进行初始化,接受学号、姓名、语文分数、数学分数和物理分数作为参数,并将其赋值给对应的属性。
类中还定义了一系列的getter方法,用于获取学生的学号、姓名、各科分数以及总分和平均分。
其中,getTotalScore()方法计算学生的总分,通过将语文分数、数学分数和物理分数相加得到。
getAverageScore()方法计算学生的平均分,首先调用了getTotalScore()方法获取学生的总分,然后将总分除以3得到平均分。
在主函数中,程序通过循环遍历学生信息数组,逐个创建学生对象并计算总分和平均分,最后格式化输出学生的信息。
3.成绩计算-2-关联类
复杂度分析:


类图:

首先定义了两个类:Score和Student。
Score类表示学生某一科目的成绩,包含私有属性usualscor(平时成绩)和endscor(期末成绩)。
Score类中的方法:
Getscor()方法用于设置平时成绩和期末成绩。
Getcal()方法计算该科目的总成绩,按照平时成绩占40%,期末成绩占60%的比例进行计算。
Getaver()方法计算该科目的平均分,首先调用Getcal()方法获得总成绩,然后除以3得到平均分。
Getaver1()方法和Getaver2()方法分别返回平时成绩和期末成绩。
Student类表示学生,包含私有属性snum(学号)、name(姓名)和三个Score对象(ma、ph、ch,分别代表数学、物理、语文成绩)。
Student类中的方法:
getSub()方法计算学生的总分,调用每个科目的Getcal()方法获取各科目的总成绩,然后相加得到总分。
getAver()方法计算学生的平均分,调用每个科目的Getaver()方法获取各科目的平均分,然后相加得到平均分。
getAver1()方法和getAver2()方法分别返回平时成绩和期末成绩的平均值。
在主函数中,创建了一个包含3个学生对象的数组stu。
使用循环读取输入的学生信息,包括学号、姓名、科目名称、平时成绩和期末成绩。根据科目名称将成绩赋值给对应的Score对象。
调用getSub()方法和getAver()方法计算学生的总分和平均分。
最后使用循环输出每个学生的学号、姓名、总分、平时平均分、期末平均分和总平均分。
总体而言,该代码实现了对学生的成绩管理和计算总分及平均分的功能。通过封装成绩相关的数据和操作于Score类和Student类中,提高了代码的可读性和可维护性。
4.课程成绩统计程序-1
复杂度分析:


类图:

这段代码是一个学生成绩计算的程序。它包含了三个类:Course、Student和CourseGrades。
-
Course类表示一门课程,包括名称(name)、性质(nature)和考核方式(assessment)等属性。所有属性都是不可变的,通过构造函数进行初始化,并提供了相应的getter方法。
-
Student类表示一个学生,包括学生的学号(id)、姓名(name)和成绩(grades)等属性。grades属性是一个Map,用于存储学生在各门课程的成绩。通过构造函数进行初始化,并提供了相应的getter和addGrade方法用于添加成绩。
-
CourseGrades类是主要的业务逻辑类,表示学生成绩计算。它包括了课程列表(courses)和学生列表(students)等属性,通过addCourse和addStudent方法来添加课程和学生。calculateGrades方法用于计算每个学生的平均成绩,并输出结果。
在calculateGrades方法中,首先创建了一些辅助的数据结构(courseTotals、courseCounts、classTotals和classCounts),用于记录课程和班级的总分和数量。然后遍历每个学生,对于每个学生的每门课程,根据成绩计算规则进行计算,并更新相应的数据结构。最后按照要求输出学生的平均成绩和每门课程的平均成绩,以及每个班级的平均成绩。
整个程序的执行流程是先读取输入信息,通过Scanner类从标准输入读取数据。根据输入的格式,解析出课程信息和学生信息,并将它们添加到CourseGrades对象中。最后调用calculateGrades方法计算并输出学生成绩。
请注意,这段代码没有提供异常处理和输入验证,对于错误的输入可能会导致程序崩溃或得到错误的结果,使用时需要保证输入的格式正确。
在每个学生的循环中,首先初始化了一些变量,包括总分(total)和计数器(count)用于计算平均分,以及班级总分(classTotal)和班级计数器(classCount)用于计算班级平均分。然后遍历该学生的所有课程,对于每门课程需要进行以下判断:
如果这门课程不存在,输出错误信息并跳过该课程。
如果这门课程的性质与学生班级不匹配,输出错误信息并跳过该课程。
如果这门课程的考核方式与成绩数组长度不匹配,输出错误信息并跳过该课程。
对于通过了所有判断的课程,根据考核方式进行成绩计算,并更新相应的数据结构。然后统计该学生的总分和计数器,并输出学生的平均成绩。同时,遍历该学生的所有课程,对于每门课程输出平均成绩或者最终成绩。
最后,在所有学生的循环之后,遍历班级的总分和计数器,计算班级平均分并输出结果。
需要注意的是,在每个学生和课程的循环中,使用了一个辅助方法getCousrseByName来根据课程名称获取课程对象。如果不存在该课程,该方法返回null。但是,由于getCousrseByName方法在null情况下没有相应的判断处理,可能导致空指针异常。因此,在使用该方法时需要做好输入验证,确保不会出现不存在的课程名称。
踩坑心得:
输入处理:使用Scanner类获取用户输入。在循环读取学生信息时,要确保输入的格式与预期一致,否则可能导致异常。
字符串分割:使用split方法将输入的学生信息按空格分割为数组。要确保输入的字段数量和顺序与代码中的要求一致,否则可能导致索引越界异常。
代码复用:代码中的一些逻辑可以进一步封装成方法或函数,以提高代码的可读性和可维护性。例如,可以将成绩计算逻辑封装在单独的方法中,并在需要时进行调用。
主要困难以及改进建议
主要困难:这份代码缺乏注释和文档,导致代码的理解和修改都比较困难。此外,代码中存在大量的重复、冗余和不必要的逻辑,使得代码的效率和可维护性受到影响。
建议改进:对于文档和注释问题,在代码编写阶段就开始编写详细的文档和注释,以便于后来的开发人员能够快速理解和修改代码。对于逻辑问题,可以使用面向对象的设计思想来减少重复和冗余的逻辑,并提高代码的可读性和可维护性。同时,可以使用测试和性能分析工具来检测和优化代码的性能问题。
主要困难:代码在处理输入和错误时存在一些问题,导致计算结果出现错误。此外,代码中的逻辑较为复杂,结构不够清晰,缺乏合适的抽象和封装。
改进:对于输入和错误处理问题,加强验证和容错能力,及时处理错误和异常情况,并提供清晰的错误提示信息。对于逻辑和结构问题,可以考虑采用模块化和面向对象的设计方式,将不同的功能封装在单独的模块中,并使用合适的接口和抽象类进行连接和调用。同时,可以使用工具和技术来分析和优化代码性能,尤其是对于大规模数据处理或复杂算法实现的场景。
总结:
在这三次作业中,初步掌握了Java语言的基本使用方法和一些独有的库方法,同时也领悟到了面向对象编程的一些思想和应用。要更加完善地总结这一过程。
- 基础语法:Java与其他编程语言不同的地方在于其特殊的语法结构和规范。因此,在学习Java时,首先要掌握它的基本语法,包括变量、数据类型、运算符、流程控制等内容。
- 库方法:Java提供了丰富的标准库和第三方库,其中许多方法可以帮助我们更好地解决问题,降低代码复杂度,提高运行速度和效率。因此,在学习Java时,我们需要熟悉Java提供的库,了解其中的常用方法和技巧,以便在实际应用中发挥其优势。
- 面向对象编程:Java是一种面向对象编程语言,因此,在学习Java时,我们需要深入理解面向对象编程的思想和原则,包括封装、继承、多态等概念和技巧。同时,我们还需要了解Java中的类和对象的定义和使用方法,掌握如何创建和管理对象,以及如何使用接口和抽象类等特性。
- 编程实践:除了理论知识之外,在学习Java时,我们还需要进行编程实践,通过实际的练习来加深对各种概念和技巧的理解和应用能力。因此,在学习过程中,我们应该尽可能多地进行实际编程练习,同时关注代码规范和风格,注重代码的可读性和可维护性。
总之,学习Java需要掌握基础语法、库方法、面向对象编程和编程实践等方面的知识和技能,同时注重代码规范和风格,以便在实际应用中发挥Java的优势。

浙公网安备 33010602011771号