泛型例题和垃圾回收机制
小提示:1.按Ctrl + Q 可以打印出来函数信息。
2.对共有的成员变量,方法和类 加注解,要用斜杠加两个星回车的方式。
一,写一个泛型类型的栈。
1 package L15; 2 3 import java.util.Arrays; 4 public class GenericStack<T> { 5 private T[] array; 6 private int top; 7 8 public GenericStack(int size){ //Alt +insert 9 this.array=(T[]) new Object[size]; //因为T是类型参数,所以不能直接new一个T类型的对象 10 this.top=0; 11 } 12 13 /** 14 * 15 * @param data 入栈 16 */ 17 public void push(T data){ 18 if(full()){ //扩容 19 this.array=Arrays.copyOf(this.array,this.array.length*2); 20 } 21 this.array[this.top++]=data; 22 } 23 24 /** 25 * 26 * @return 出栈 27 */ 28 public T pop(){ 29 if(empty()){ //先判断栈空 30 return null; 31 } 32 T data =this.array[--this.top]; //注意this.top的作用域为整个类中,此处减过之后,下一行就不用减了 33 this.array[this.top]=null; //当引用变量为空时,gc将回收 34 return data; 35 } 36 /** 37 * 获取栈顶元素 38 */ 39 public T back(){ 40 if(this.top==0){ //先判断栈空 41 return null; 42 } 43 return this.array[this.top-1]; 44 } 45 /** 46 * 判断栈空 47 */ 48 public boolean empty(){ 49 return this.top==0; 50 } 51 /** 52 * 栈满 53 */ 54 public boolean full(){ 55 return this.top==this.array.length; 56 } 57 public int size(){ 58 return this.top; 59 } 60 61 62 63 public static void main(String[] args) throws InterruptedException{ 64 GenericStack<String> G=new GenericStack(20); 65 for (int i = 0; i < 20;i++ ) { 66 G.push(String.valueOf(i+1)); 67 } 68 while(!G.empty()){ 69 System.out.print(G.pop()+" "); 70 } 71 } 72 }
运行结果:
二,定义一个学生类型的栈(通过泛型方式实现)
1 package L15; 2 3 import java.util.Arrays; 4 class Student implements Comparable<Student>{ 5 6 private Integer id; 7 private String name; 8 private Integer age; 9 public Student(Integer id,String name,Integer age){ 10 this.id=id; 11 this.name=name; 12 this.age=age; 13 } 14 15 @Override 16 public String toString() { 17 return "Student:" + "id=" + id + " name=" + name + "age=" + age ; 18 } 19 20 @Override 21 public Integer compareTo( Student o) { 22 //st=(Student)o; 23 return this.id.compareTo(o.id); //注意若要用compareTo()来比较,则必须保证传进来的是包装类型,如Integer ,所以简单类型 int 不行。 24 } 25 } 26 27 /** 28 * 泛型的顺序栈 29 */ 30 public class GenericStack<T> { 31 private T[] array; 32 private int top; 33 34 public GenericStack(int size){ //Alt +insert 35 this.array=(T[]) new Object[size]; 36 this.top=0; 37 } 38 39 /** 40 * 41 * @param data 入栈 42 */ 43 public void push(T data){ 44 if(full()){ //扩容 45 this.array=Arrays.copyOf(this.array,this.array.length*2); 46 } 47 this.array[this.top++]=data; 48 } 49 50 /** 51 * 52 * @return 出栈 53 */ 54 public T pop(){ 55 if(empty()){ //先判断栈空 56 return null; 57 } 58 T data =this.array[--this.top]; //注意this.top的作用域为整个类中,此处减过之后,下一行就不用减了 59 this.array[this.top]=null; //当引用变量为空时,gc将回收 60 return data; 61 } 62 /** 63 * 获取栈顶元素 64 */ 65 public T back(){ 66 if(this.top==0){ //先判断栈空 67 return null; 68 } 69 return this.array[this.top-1]; 70 } 71 /** 72 * 判断栈空 73 */ 74 public boolean empty(){ 75 return this.top==0; 76 } 77 /** 78 * 栈满 79 */ 80 public boolean full(){ 81 return this.top==this.array.length; 82 } 83 public int size(){ 84 return this.top; 85 } 86 87 88 89 public static void main(String[] args) throws InterruptedException{ 90 GenericStack<Student> GG=new GenericStack(5); //定义了一个学生类型的栈 91 GG.push(new Student(101,"zhangsan",20)); //往栈里放元素(元素类型为学生类) 92 GG.push(new Student(103,"lisi",20)); 93 GG.push(new Student(102,"wangwu",20)); 94 GG.push(new Student(101,"张三",20)); 95 GG.push(new Student(101,"张三",20)); 96 GG.pop(); //出栈 97 GG.pop(); 98 System.gc(); 99 Thread.sleep(100000); 100 Student[] stu=new Student[GG.size()]; //定义一个学生类型的数组,数组名为stu 101 for(int i=0;!GG.empty();i++){ //将栈里剩余的元素放到这个学生类型的数组中 102 stu[i]=GG.pop(); 103 } 104 Arrays.sort(stu); //对数组进行排序(要对student对象进行排序,要在类名后实现Comparable接口, 105 //并在student类中对compareTo()方法进行重写 106 System.out.println(Arrays.toString(stu)); //对数组元素进行打印,若元素为自定义类型, 107 // 则在该类型中要对toString()方法进行重写 108 int[] arr=new int[]{1,1,1,2}; 109 System.out.println(Arrays.toString(arr)); //因为arr为Interage类型,该类型在底层已经对toString()方法进行重写过了 110 111 } 112 }
在编码的过程中因为将id定义成了简单类型int,所以在底下使用compareTo()方法时,一直报错。
在当我将所有简单类型换成包装类型Integer时,则错误消失。这是因为包装类型Integer对compareTo()方法
进行重写了,而简单类型没有,所以简单类型不能调用compareTo()方法。
***************************************************************************************************************
**********************************************************************************************************************
所以要用简单类型进行比较时,需要改成如下代码。
三,关于垃圾回收机制。
如果没有被其他引用变量所引用,这个对象就可以被GC回收了,需要手动启动它。如:System.GC;
可以在命令提示符(cmd)中查看,对象有没有被回收。
方式:cmd -> jps -> jmap -histo:live 进程号 > 文件名 回车
start. 回车
举例:
**************************************************************************************
若出栈方式如上面所定义的,则启动垃圾回收机制,前面pop()出来的这些学生对象仍不会不会被回收,
因为pop()是通过将top指针移动来实现的,而被pop()了的对象仍被变量引用着。所以此时用cmd查看时,会
看到进程中有5个Student对象。
所以必须要将不用的对象置为null,这样垃圾回收机制才能将不用的对象回收掉。
例如将出栈函数这样写:
此时运行时,在进程中就只能看到3个对象。