Java编程内存分析简要

  • 需求1:计算五名学生,一门课程的平均分。
    • 分析数据存储:
      • 数组存储数据(1)
      • 数组存储数据(2)
      • 数组存储数据(3)
    • 关于需求1使用面向对象程序设计思想的思考。
  • 需求2:计算五名学生,三门课程的平均分。
    • 设计类
    • 设计类的成员
    • 代码实现
    • 增加需求:根据每名同学平均成绩进行排序输出。
      • 第1步:定义排序类
      • 第2步:使用Arrays类的sort方法排序
  • 需求3:计算多名学生,多门课程的平均分
    • 分析:
    • 设计:
    • 代码实现
  • 需求4:计算多名学生,多门课程的平均分,并分别按数学、语文、英语成绩排序输出。

需求1:计算五名学生,一门课程的平均分。

分析数据存储:

Java语言中存储数据的方式有几种?
(1)简单变量,例如int age;
(2)数组,例如,int []age,定义一个数组相当于一次定义了多个变量,这些变量都是相同类型的。
(3)集合,集合存储不同类型的多个变量

数组存储数据(1)

package tests;public class Test1 {public static void main(String[] args) {//定义数组存储成绩int[] score = null; //存入成绩for(int i = 0; i < score.length;i++) { score[i] = 80;}//打印成绩for(int i : score) {System.out.print(i+",");}}
}

运行时出现空指针异常。

数组存储数据(2)

Test1之所以出现空指针异常是由于没有给数组score申请内存,接下来给数组score申请内存后如下:

package tests;public class Test2 {public static void main(String[] args) {int[] score = new int[5];for(int i = 0; i < score.length;i++) {score[i] = 80 + i;}for(int i : score) {System.out.println(i+"分");}}
}

数组存储数据(3)

Test2中虽然解决了空指针异常的情况,但是,却无法知道成绩具体所指向的学生是谁??所以要先创建一个学生类(Students),具体如下:

package tests;public class Test3 {public static void main(String[] args) {// 定义引用类型数组Students[] stu = new Students[2];// 给数学成绩赋值for(int i = 0; i < stu.length;i++) {stu[i].math = 80;}//打印成绩for(Students i : stu) {System.out.println(i+"分");}}
}


解析:出现空指针异常,这是由于只创建了Studnets类,但是没有创建学生对象new Students();
(连学生对象都不存在,如何给学生对象的数学成绩赋值呢,所以报空指针异常。)

解决办法:创建学生后再给数学成绩赋值。
student class

package tests;public class Students {int math; //数学成绩
}

Test Class

package tests;public class Test4 {public static void main(String[] args) {Students[] stu = new Students[2];//创建学生对象for(int i = 0; i < stu.length;i++) {stu[i] = new Students();}for(int i = 0; i < stu.length;i++) {stu[i].math = 80 + i;}for(Students i : stu) {System.out.println(i.math+"分");}}
}


解释:
首先要明白
基本类型中存储的是真正的数据,引用数据类型存储的都是地址编号。
Students类是引用数组类型,因此,stu[0]stu[1]存储的是地址,而数学成绩是基本数据类型(int),其存储的是值。

关于需求1使用面向对象程序设计思想的思考。

相对于简单变量与数组解决这个需求1时,数组更好,因为数组的扩展性好,例如更改了学生数量,数组的维护成本小得多.

但是需求1中的数组实现方式中,如果要增加课程,应该怎么设计呢?显然需要增加数组的个数,让一个数组表示一门课程,有几门课程就定义几个数组。这种设计方法没有体现面向对象的思想,因此无法使用面向对象的特征来解决需求变化的问题.

关于需求1使用面向对象程序设计思想的思考
面向对象认为:万物皆对象,也就是任何事物都是对象.
更具面向对象的思想并结合需求1来设计该程序:

 将班级设计为:班级类(名称,学生,平均分)将学生设计为:学生类(姓名,数学成绩)将程序启动的文件命名为:Tes t.

Student

package tests;public class Student {String name; //姓名int maht;//数学成绩
}

ClassInfo

package tests;public class ClassInfo {String name; //班级名称Student[] stus = new Student[5];//学生public int getMathAverage() {  //数学成绩平均值int sum = 0;for(int i = 0;i < stus.length;i++) {sum += stus[i].maht;}return sum/stus.length;}
}

Test

package tests;import java.util.Random;public class Test {public static void main(String[] args) {// 创建班级ClassInfo cla = new ClassInfo();cla.name = "史莱克学院n期";// 输入班级学生的信息for(int i = 0;i < cla.stus.length;i++) {cla.stus[i].name = "唐"+(i+1);cla.stus[i].maht = new Random().nextInt(40) + 60;System.out.println(cla.stus[i].name + " " + cla.stus[i].maht);}// 计算平均数学成绩int mathAverage = cla.getMathAverage();System.out.println("数学平均成绩:"+mathAverage);   }
}

运行结果:“java.lang.NullPointerException”
分析如下图:

解析:
在创建班级时,学生类也就一并创建了,但是没有创建学生对象;因此在给具体学生对象输入信息时,先要实现对象的实例化。

// 实例化学生对象并输入班级学生的信息for(int i = 0;i < cla.stus.length;i++) {cla.stus[i] = new Student(); //实例化学生对象cla.stus[i].name = "唐"+(i+1);cla.stus[i].maht = new Random().nextInt(40) + 60;}

创建学生对象之后,运行后的Java内存分配如下图:

需求2:计算五名学生,三门课程的平均分。

设计类

面向对象中如何分析问题,设计类,设计类的成员.
分析类:找出问题中描述的名词,每个名词设计为一个类.

例如: 统计班级五个学生数学、语文和英语成绩平均分。

其中的 班级, 学生是名词,应该设计为类,因此设计一个班级类和一个学生类,用类图表示类,如下所示

设计类的成员

例如:班级中有学生,因此学生是班级的一个属性;平均分是班级的属性;将班级类设计如下

学生类有数学、语文和英语成绩和学生姓名,学生类的类图如下

代码实现

Student

package tests;public class Student {String name; //姓名int math;//数学成绩int ch; //语文成绩int en; //英语成绩
}

ClassInfo

package tests;public class ClassInfo {String name; //班级名称Student[] stus = new Student[5];//学生int mathAvg; //数学平均成绩int chAvg; //语文平均成绩int enAvg; //英语平均成绩public int getMathAverage() {  //数学成绩平均值int sum = 0;for(int i = 0;i < stus.length;i++) {sum += stus[i].math;}mathAvg = sum/stus.length;return mathAvg;}public int getChAverage() {  //语文成绩平均值int sum = 0;for(int i = 0;i < stus.length;i++) {sum += stus[i].ch;}chAvg = sum/stus.length;return chAvg;}public int getEnAverage() {  //英语成绩平均值int sum = 0;for(int i = 0;i < stus.length;i++) {sum += stus[i].en;}enAvg = sum/stus.length;return enAvg;}
}

Test

package tests;import java.util.Random;public class Test {public static void main(String[] args) {// 创建班级ClassInfo cla = new ClassInfo();cla.name = "史莱克学院n期";// 实例化学生对象并输入班级学生的信息System.out.println("\n\t\t"+cla.name+"成绩单\n\n\t姓名\t数学\t语文\t英语\n");for(int i = 0;i < cla.stus.length;i++) {cla.stus[i] = new Student();//创建学生对象cla.stus[i].name = "唐"+(i+1);cla.stus[i].math = new Random().nextInt(40) + 60;cla.stus[i].ch = new Random().nextInt(40) + 60;cla.stus[i].en = new Random().nextInt(40) + 60;System.out.println("\t"+cla.stus[i].name+ "\t"+cla.stus[i].math+ "\t"+cla.stus[i].ch+ "\t"+cla.stus[i].en);}// 输出平均成绩System.out.println("\n\t数学平均成绩:"+cla.getMathAverage());System.out.println("\t语文平均成绩:"+cla.getChAverage());System.out.println("\t英语平均成绩:"+cla.getEnAverage());}
}

增加需求:根据每名同学平均成绩进行排序输出。

第1步:定义排序类

首先按照数学排序,排序类必须是实现了java.util.Comparator接口的类,并且要实现int compare(Student s1, Student s2)比较方法,该方法返回int类型的数据,当返回值大于0时,表示s1大于s2,当返回值等于0时,表示s1等于s2,当返回值小于0时表示s1小于s2.

AverageScoreComparator

package tests;import java.util.Comparator;public class AverageScoreComparator implements Comparator<Student>{@Overridepublic int compare(Student o1, Student o2) {return (o1.math + o1.ch + o1.en) - (o2.math + o2.ch + o2.en);}}

ClassInfo类中定义查看成绩的方法shouAvgScore().

public void showAvgScore() {System.out.println("\t姓名\t平均 成绩");for(int i = 0;i < stus.length;i++) {System.out.println("\t"+stus[i].name+"\t平均 成绩"+(stus[i].math + stus[i].ch + stus[i].en)/3);}}

第2步:使用Arrays类的sort方法排序

Arrays.sort(cla.stus,new AverageScoreComparator());

完整的测试类如下:

package tests;import java.util.Arrays;
import java.util.Random;public class Test {public static void main(String[] args) {// 创建班级ClassInfo cla = new ClassInfo();cla.name = "史莱克学院n期";// 实例化学生对象并输入班级学生的信息System.out.println("\n\t\t"+cla.name+"成绩单\n\n\t姓名\t数学\t语文\t英语\n");for(int i = 0;i < cla.stus.length;i++) {cla.stus[i] = new Student();//创建学生对象cla.stus[i].name = "唐"+(i+1);cla.stus[i].math = new Random().nextInt(40) + 60;cla.stus[i].ch = new Random().nextInt(40) + 60;cla.stus[i].en = new Random().nextInt(40) + 60;System.out.println("\t"+cla.stus[i].name+ "\t"+cla.stus[i].math+ "\t"+cla.stus[i].ch+ "\t"+cla.stus[i].en);}// 输出平均成绩System.out.println("\n\t数学平均成绩:"+cla.getMathAverage());System.out.println("\t语文平均成绩:"+cla.getChAverage());System.out.println("\t英语平均成绩:"+cla.getEnAverage());System.out.println("排序前三门成绩平均分");cla.showAvgScore();Arrays.sort(cla.stus,new AverageScoreComparator());System.out.println("排序后三门成绩平均分");cla.showAvgScore();}
}

结果展示:

需求3:计算多名学生,多门课程的平均分

并按数学、语文、英语和总成绩排序。

分析:

被操作的数据是数学、语文和英语,数学、语文和英语属于学生类;需要操作的内容是平均分,平均分属于班级,人数不确定所以不能使用数组,应该使用集合存储数据。

设计:

设计学生类:定义数学、语文和英语属性
设计班级类:定义学生类的集合,定义班级的平均分,定义计算平均分的方法
设计测试类:运行程序

代码实现

Student

public class Student {private String name;private int math;private int ch;private int en;public Student(String name, int math, int ch, int en) {this.name = name;this.math = math;this.ch = ch;this.en = en;}public Student() {}public String getName() {return name;}public int getMath() {return math;}public int getCh() {return ch;}public int getEn() {return en;}public void setName(String name) {this.name = name;}public void setMath(int math) {this.math = math;}public void setCh(int ch) {this.ch = ch;}public void setEn(int en) {this.en = en;}
}

ClassInfo

import java.util.List;public class ClassInfo {private List students;private int avgMath;private int avgCh;private int avgEn;public List getStudents() {return students;}public void setStudents(List students) {this.students = students;}public int getAvgMath() {int sum = 0;for (int i = 0; i < students.size(); i++) {Student stu = (Student) students.get(i);sum += stu.getMath();}avgMath = sum / students.size();return avgMath;}public int getAvgCh() {int sum = 0;for (int i = 0; i < students.size(); i++) {Student stu = (Student) students.get(i);sum += stu.getCh();}avgCh = sum / students.size();return avgCh;}public int getAvgEn() {int sum = 0;for (int i = 0; i < students.size(); i++) {Student stu = (Student) students.get(i);sum += stu.getEn();}avgEn = sum / students.size();return avgEn;}
}

Test

import java.util.ArrayList;
import java.util.List;public class Test {public static void main(String[] args) {//      创建班级ClassInfo c1 = new ClassInfo();
//      创建学生Student s1 = new Student("唐1",77,77,77);Student s2 = new Student("唐2",78,78,78);Student s3 = new Student("唐3",79,79,79);Student s4 = new Student("唐4",80,80,80);Student s5 = new Student("唐5",81,81,81);
//      将学生存储到集合中List students = new ArrayList();students.add(s1);students.add(s2);students.add(s3);students.add(s4);students.add(s5);
//      将集合存储到班级中c1.setStudents(students);
//      输出学生的平均成绩System.out.println("平均数学成绩:"+c1.getAvgMath());System.out.println("平均数学成绩:"+c1.getAvgCh());System.out.println("平均数学成绩:"+c1.getAvgEn());}
}

需求4:计算多名学生,多门课程的平均分,并分别按数学、语文、英语成绩排序输出。

只需要在需求3的基础上加以改进就行,不过首先要知道一下两点:

  • 对数组排序,java提供了java.util.Arrays类,调用sort方法实现排序,需要传入比较器
  • 对集合排序,java提供了java.util.Collections类,调用sort方法实现排序,需要传入比较器

针对于数学、语文和英语分别进行比较器的设计如下:
MathComparator

import java.util.Comparator;public class MathComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.getMath() - o2.getMath();}
}

ChComparator

import java.util.Comparator;public class ChComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.getCh() - o2.getCh();}
}

EnComparator

import java.util.Comparator;public class EnComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.getEn() - o2.getEn();}
}

接下来还需要在ClassInfo中添加,查看成绩的方法,如下所示:

public void showByMant(){for (int i = students.size() - 1; i >= 0; i--) {Student stu = (Student) students.get(i);System.out.println(stu.getName() + " " + stu.getMath());}}public void showByCh(){for (int i = students.size() - 1; i >= 0; i--) {Student stu = (Student) students.get(i);System.out.println(stu.getName() + " " + stu.getCh());}}public void showByEn(){for (int i = students.size() - 1; i >= 0; i--) {Student stu = (Student) students.get(i);System.out.println(stu.getName() + " " + stu.getEn());}}

最后在Test类中添加如下代码就可以测试结果了:

//      数学成绩排序后输出Collections.sort(c1.getStudents(),new MathComparator());c1.showByMant();Collections.sort(c1.getStudents(),new ChComparator());c1.showByCh();Collections.sort(c1.getStudents(),new EnComparator());c1.showByEn();

Java编程内存分析简要相关推荐

  1. Java程序内存分析

    2019独角兽企业重金招聘Python工程师标准>>> Java程序内存分析:使用mat工具分析内存占用 http://my.oschina.net/biezhi/blog/2862 ...

  2. Java 堆内存分析

    Java 堆内存工具jmap 打印当前 Java 堆内存信息 jmap -histo[:live] <pid> # 打印当前进程中类实例信息 导出Java 堆内存到文件 jmap -dum ...

  3. 面试积累(java的内存分析)

    关于java中的内存分析: 1 首先,java中的内存总体分为了四个部分,分别为stack segment,heap segment,code segment,data segment.即 栈区,堆区 ...

  4. java 堆内存分析_JVM内存堆布局图解分析

    JAVA能够实现跨平台的一个根本原因,是定义了class文件的格式标准,凡是实现该标准的JVM都能够加载并解释该class文件,据此也可以知道,为啥Java语言的执行速度比C/C++语言执行的速度要慢 ...

  5. java怎么看内存值_【java】内存分析

    在J2SE中,通过进行内存分析,可以让我们更好的理解我们的程序在内存中是怎么被分配内存的.也能让我们更好的理解我们的代码是怎么运行的. 对于我自己来说分析内存也是一件很有趣的事情.所以下面通过一个例子 ...

  6. Java JVM内存分析

    2019独角兽企业重金招聘Python工程师标准>>> JVM常见参数及溢出分析工具和方法 JDK1.6.45常用基本参数 -server 服务模式启动  -verbose:gc 开 ...

  7. Java程序内存分析:使用mat工具分析内存占用

    1. 用jmap生成堆信息 2. 将堆信息导入到mat中分析 3. 生成分析报告 Histogram Dominator Tree Top consumers Leak Suspects MAT 不是 ...

  8. java项目内存分析jmap命令+MAT工具

    一.分析背景 在服务器上运行java项目服务时,由于服务所实现的功能导致每个项目在消耗服务器系统内存上有所差异.如果在项目中某个功能模块中作了不良好的操作导致占用的资源未能及时释放就会导致内存泄露,服 ...

  9. java编程 内存_Java编程技术之浅析JVM内存

    JVM JVM->Java Virtual Machine:Java虚拟机,是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的. 基本认知: ...

最新文章

  1. javascript回车完美实现tab切换功能
  2. Comcast在美国境内遭遇大面积宕机和连接中断问题
  3. C#使用集合组织相关数据
  4. python爬取内容乱码_python爬取html中文乱码
  5. c语言flappy bird代码,Flappy bird源代码(略吊)
  6. ubuntu下命令行设置壁纸
  7. Codeigniter处理用户登录验证后URL跳转
  8. 利用计算机教学的体会,教师计算机教学学习体会
  9. 张孝祥javascript视频教程
  10. 夯实Java基础系列21:Java8新特性终极指南
  11. urlrewrite java_Java中URL重写(urlrewrite+Maven)
  12. termux使用记录
  13. 软件架构风格-数据流风格
  14. Nordic 52832工程报错undefined reference to `__start_pwr_mgmt_data'解决办法
  15. currentlyFocusedField is deprecated and will be removed in a future release解决方法记录
  16. 计算机国二复习攻略,全国计算机等级考试二级复习指导及应试技巧二
  17. 四种属性范围(重点)
  18. 使用PS快速保存多种尺寸的图标
  19. org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
  20. 程序员如何避免「温水煮码农」

热门文章

  1. 关于texpad编译后无法找到目录的.toc文件
  2. 相片打印机原理_照片打印机有哪些特点 照片打印机多少钱【详解】
  3. 黑马训练营-毕业设计项目(超全)
  4. 电脑启动项和系统引导项设置
  5. 算法概念【PPT整理】
  6. BeautifulSoup previous_siblings next_siblings parents对比
  7. 7Z命令在linux下的使用
  8. PAT 1085 PAT单位排行 (Microsoft_zzt)
  9. Three Days to See
  10. 人类创造出来的世界——电子世界