一、什么是数组
数组就是一个容器,用来存一批同种类型的数据的。
比如:想要存储 20,10,80,60,90 这些数据。 我们可以把代码写成这样
int[] array = {20,10,80,60,90};
比如:想要存储 “牛二“,“西门“,“全蛋“ 这些数据。我们可以把代码写成这样
String[] names = {"牛二", "西门", "全蛋"};
结论:遇到批量数据的存储和操作时,数组比变量更适合。
二、数组的定义和访问
数组有两种初始化的方式,一种是静态初始化、一种是动态初始化。
2.1 数组的静态初始化
所谓静态初始化指的是:在定义数组时直接给数组中的数据赋值。
1. 静态初始化标准格式:
数据类型[] 变量名 = new 数据类型[]{元素1,元素2,元素3};
按照格式定义int类型、double类型数组
//定义数组,用来存储多个年龄
int[] ages = new int[]{12, 24, 36}
//定义数组,用来存储多个成绩
double[] scores = new double[]{89.9, 99.5, 59.5, 88.0};
2. 静态初始化简化格式(常用):
Java语言的设计者为了简化定义数组的写法,还为静态初始化提供了一种简化写法
数据类型[] 变量名 = {元素1,元素2,元素3};
使用简化格式定义int类型、double类型数组
//定义数组,用来存储多个年龄
int[] ages = {12, 24, 36}
//定义数组,用来存储多个成绩
double[] scores = {89.9, 99.5, 59.5, 88.0};
3. 注意!!
- 定义数组时,
数据类型[] 数组名
也可写成数据类型 数组名[]
//以下两种写法是等价的。但是建议大家用第一种,因为这种写法更加普遍
int[] ages = {12, 24, 36};
int ages[] = {12, 24, 36}
4. 数组在计算机中的基本原理
我们知道数组是怎么定义的之后,那么接下来看一下数组在计算机中的基本原理。
我们以int[] ages = {12,24,36};
这句话为例,看一下这句话到底在计算机中做了那些事情。
- 首先,左边
int[] ages
表示定义了一个数组类型的变量,变量名叫ages - 其次,右边
{12,24,36}
表示创建一个数组对象,你完全可以把它理解成一个能装数据的东西。这个对象在内存中会有一个地址值[I@4c873330
,每次创建一个数组对象都会有不用的地址值。 - 然后,把右边的地址值
[I@4c873330
赋值给左边的ages变量 - 所以,ages变量就可以通过地址值,找到数组这个东西。
2.2 数组的元素访问
各位同学,通过刚才的学习,我们知道数组是用来存储数据的。那么数组中存储的数据又如何访问呢?这里所说的访问,意思就是获取中数组中数据的值、或者给数组中的数据赋值。
这里先给大家统一几个概念,数组中存储的数据我们叫做元素;而且数组中的每一个元素都有一个编号与之对应,我们把这个编号叫做索引,这个索引是从0依次递增的整数。如下图所示
2.3 数组的遍历
直接拿for循环遍历索引。
略。
2.4 数组的动态初始化
各位同学,刚才我们初始化数组时,都是直接将元素写出来。但是还有另一个初始化数组的方式叫 动态初始化。
动态初始化不需要我们写出具体的元素,而是指定元素类型和长度就行。格式如下
//数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[3];
下面是动态初始化数组的原理图。我们发现int[] arr
其实就是一个变量,它记录了数组对象的地址值,而且数组中的元素默认值是0。
注意:
使用动态初始化定义数组时,根据元素类型不同,默认值也有所不同。
三、数组在计算机中的执行原理
3.1 数组的执行原理,Java程序的执行原理
我们以下面的代码,来讲解变量、数组的执原理。
public class ArrayDemo1 {
public static void main(String[] args) {
int a = 10;
System.out.println(a);
int[] arr = new int[]{11, 22, 33};
System.out.println(arr);
System.out.println(arr[1]);
arr[0] = 44;
arr[1] = 55;
arr[2] = 66;
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
}
}
前面我们给大家讲过,程序是在内存中执行的。实际上Java程序是把编译后的字节码加载到Java虚拟机中执行的。
Java为了便于虚拟机执行Java程序,将虚拟机的内存划分为 方法区、栈、堆、本地方法栈、寄存器 这5块区域。同学们需要重点关注的是 方法区、栈、堆。
下面把每一个块内存区域作用介绍一下,我们大致只需要知道每一部分存储什么内容就行。
- 方法区:字节码文件先加载到这里
- 栈:方法运行时所进入的内存区域,由于变量在方法中,所以变量也在这一块区域中
- 堆:存储new出来的东西,并分配地址。由于数组是new 出来的,所以数组也在这块区域。
下面是上面案例执行的内存原理如下图所示,按照① ② ③ ④ ⑤ ⑥ 的标记的顺序来看。
总结一下int a = 10
与 int[] arr = new int[]{11,22,33}的区别
- a是一个变量,在栈内存中,a变量中存储的数据就是10这个值。
- arr也是一个变量,在栈中,存储的是数组对象在堆内存中的地址值
// 这里的int a是一个基本类型变量,存储的是一个数值
int a = 10 ;
//这里的int[] arr是一个引用类型的变量,存储的是一个地址值
int[] arr = new int[]{44,55,66};
3.2 多个变量指向同一个数组的问题
各位同学,我们了解了数组在内存中的执行原理。我们知道数组类型的变量,指向的是堆内存中数组对象的地址。但是在实际开发中可能存在一种特殊情况,就是多个变量指向同一个数组对象的形式。
public class ArrayDemo2 {
public static void main(String[] args) {
// 目标:认识多个变量指向同一个数组对象的形式,并掌握其注意事项。
int[] arr1 = {11, 22, 33};
// 把int类型的数组变量arr1赋值给int类型的数组变量arr2
int[] arr2 = arr1;
System.out.println(arr1);
System.out.println(arr2);
arr2[1] = 99;
System.out.println(arr1[1]);
arr2 = null; // 拿到的数组变量中存储的值是null
System.out.println(arr2);
//System.out.println(arr2[0]);
//System.out.println(arr2.length);
}
}
刚执行完int[] arr1 = {11,22,33};
时,内存原理如下
当执行完int[] arr2 = arr1;
后,内存原理如下
当执行到arr2[1]=99;时
,内存原理如下
总结一下:
-
两个变量指向同一个数组时,两个变量记录的是同一个地址值。
-
当一个变量修改数组中的元素时,另一个变量去访问数组中的元素,元素已经被修改过了。