7.3 栈数据结构

  常见的数据结构:栈、队列、链表、数组、树、图、堆、散列等等,目前我们首先第一个接触到的是stack数据结构,如下图所示:

java 堆栈模拟队列 java堆栈和栈的图解_java


  栈又叫做堆栈,仅允许在表的一端进行插入和删除运算,这一端被称之为栈顶,相对的,把另一端称为栈低,向一个栈插入新元素又称之为进栈,入栈或者压栈(push),从一个栈删除元素又称之为出栈、退栈或弹栈,他是把栈顶元素删除掉,使其临近的元素称为新的栈顶。如下图所示:

java 堆栈模拟队列 java堆栈和栈的图解_数据结构_02


  由图可以看出,栈数据结构的特点:先进后出,后进先出原则

7.4 方法执行过程中内存的变化

我们先看一张图片:

java 堆栈模拟队列 java堆栈和栈的图解_数据结构_03


  上图是一张标准的java虚拟机内存结构图,目前我们只看其中的方法去和栈,其中方法区中主要存储的是.class字节码文件,栈是在方法执行时需要在栈内存中分配空间。java程序开始执行的时候,首先通过类加载器子系统找到硬盘上的字节码文件,然后将其加载到java虚拟机内存的方法区中,然后开始调用字节码文件中的main()方法,并将main()压栈到栈内存中,作为栈底。并且按照栈数据结构的特点,main()是最先被执行,并最后执行结束(目前来说是这样)。只有在方法执行,被调用了,栈空间才会被启动。

  下面就是一个main()方法的执行过程中内存空间的变化过程,其中main()方法中还包含了m1()方法和m2()方法:

java 堆栈模拟队列 java堆栈和栈的图解_数据结构_04


  文字说明

1、首先类加载子系统会将需要的字节码文件全部都装载入方法区中,接着就开始执行主文件中的main()方法,并将main()方法栈桢压栈到栈内存中

2、main()方法中首先调用的是m1()方法,所以接着把m1()方法的栈桢压入到栈方法去区。

3、紧接着调用m1()方法中的m2()方法,并将m2()方法的栈桢压入到栈栈内存中,此时栈内存就有了三个方法的栈桢

4、接下来m2()方法结束,m2()方法的栈桢pop

5、接下来m1()方法结束,m1()方法的栈桢pop

6、接下来main()方法结束,main()方法的栈桢pop,栈空了,程序结束

7.5 方法重载/overload(掌握)

  方法重载指的是在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数个数(最常见的重载方法就是println()方法),调用重载方法时,java编译器能够通过调用方法的参数类型和参数个数来选择一个合适的方法。注:方法重载与修饰符无关
  满足下面三个条件即构成方法重载:
1、在同一个类中
2、具有相同的方法名
3、参数的类表不同:个数不同算不同,顺序不同算不同,类型不同算不同

7.5 方法递归

  什么是方法递归,先看一段代码:

public class RecursionTest01{
	public static void main(String[] args){
		m();
	}
	
	public static void m(){
		System.out.printlm("m1方法执行");
		m1();
		System.out.println("m1方法结束");
	}
}

  以上的m1方法就是一个方法递归,但是这样可能会形成死循环,比如上面的程序,没有一个方法结束的条件,那么m1方法就会一直被调用,直到栈内存溢出,报错。

  下面我们来研究一下使用递归来计算1~N的和

public class SumN{
	public static void main(String[] args){
		int sum;
		int a = 5;
		sum = computerSum(a);
		System.out.println();
	}
	public static int computerSum(int a){
		int sum;
		while(a>0){
			sum = a + computerSum(a-1);
		}
		return sum;
	}
}