JAVA中数组的基本概念与用法
1. 数组的定义与特点
- 数组的一种引用数据类型
- 数组中可以同时存放多个数据,但是数据的类型必须统一
- 数组的长度在开始时就需要确定,在程序运行期间是不可改变的
- 虽然可以使用数组的扩容机制来扩充数组的长度,但是这个方法也比较麻烦
2. 数组的初始化
-
数组的初始化方式有两种
- 动态初始化
- 静态初始化
动态初始化特点:
在创建数组的时候,直接指定数组当中的数据元素个数。
动态初始化数组的格式:
数据类型[] 数组名称 = new 数据类型[数组长度];
解析含义:
左侧数据类型:也就是数组当中保存的数据,全都是统一的什么类型
左侧的中括号:代表是一个数组
左侧数组名称:给数组取一个名字
右侧的new:代表创建数组的动作
右侧数据类型:必须和左边的数据类型保持一致
右侧中括号的长度:也就是数组当中,到底可以保存多少个数据,是一个int数字
- 动态创建数组的示例代码:
// 数据类型[] 数组名称 = new 数据类型[数组长度]; // 定义一个int类型的数组,可以存放10个数据 int[] arrayA = new int[10]; // 给创建的数组赋值 for (int i = 0; i < 10; i ++){ arrayA[i] = i; } // 输出数组中的值 for (int i = 0; i < 10; i ++){ System.out.print(arrayA[i]); }
-
静态初始化数组
-
静态初始化数组的特点:
在创建数组的时候,不直接指定数据个数多少,而是直接将具体的数据内容进行指定。
-
静态初始化基本格式:
数据类型[] 数组名称 = new 数据类型[] { 元素1, 元素2, ... };
-
注意事项:
虽然静态初始化没有直接告诉长度,但是根据大括号里面的元素具体内容,也可以自动推算出来长度
-
静态初始化数组示例代码
// 数据类型[] 数组名称 = new 数据类型[] { 元素1, 元素2, ... }; // 创建一个数组,一开始数组中就有1,2,3,4,5 这些值 int [] arrayA = new int[] {1, 2, 3, 4, 5,}; // 输出数组中的使用元素 for (int i = 0; i < arrayA.length; i ++){ System.out.print(arrayA[i]); }
-
-
数组初始化的省略格式
-
标准格式:
数据类型[] 数组名称 = new 数据类型[] { 元素1, 元素2, ... };
-
省略格式:
数据类型[] 数组名称 = { 元素1, 元素2, ... };
-
注意事项:
- 静态初始化没有直接指定长度,但是仍然会自动推算得到长度。
- 静态初始化标准格式可以拆分成为两个步骤。
- 动态初始化也可以拆分成为两个步骤。
- 静态初始化一旦使用省略格式,就不能拆分成为两个步骤了。
-
使用建议:
如果不确定数组当中的具体内容,用动态初始化;否则,已经确定了具体的内容,用静态初始化。
-
示例代码
-
// 省略格式的静态初始化
int[] arrayA = { 10, 20, 30 };
// 静态初始化的标准格式,可以拆分成为两个步骤
int[] arrayB;
arrayB = new int[] { 11, 21, 31 };
// 动态初始化也可以拆分成为两个步骤
int[] arrayC;
arrayC = new int[5];
// 静态初始化的省略格式,不能拆分成为两个步骤。(错误写法,编译器直接报错)
// int[] arrayD;
// arrayD = { 10, 20, 30 };
}
3. 获取数组中的元素
-
使用动态初始化数组的时候,其中的元素将会自动拥有一个默认值。规则如下:
如果是整数类型,那么默认为0;
如果是浮点类型,那么默认为0.0;
如果是字符类型,那么默认为'\u0000';
如果是布尔类型,那么默认为false;
如果是引用类型,那么默认为null。 -
注意事项:
静态初始化其实也有默认值的过程,只不过系统自动马上将默认值替换成为了大括号当中的具体数值。
-
对于数组而言,数组的下标是从0开始的,访问的时候需要注意。
// 创建一个数组
int[] arrayA = new int[10];
// 给数组中添加元素,数组的下标从0开始;
arrayA[0] = 1;
arrayA[1] = 2;
arrayA[2] = 3;
// 直接定义数组的名称,将输出数组在内存中经过哈希得到的地址值
System.out.println(arrayA);
// 使用Arrays中的toString()方法输出数组,
// 从得到的结果中会发现没有赋值的位置会自动使用0补齐。
System.out.println(Arrays.toString(arrayA));
// 获取数组中一个指定位置的元素值
// 例如:获取下标为0的元素值
System.out.println(arrayA[0]);
4.Java中的内存划分(图片来自网络)
5. 假设一个数组的内存图
- 栈中的变量地址指向堆中的内存地址
6. JAVA中的浅拷贝
-
如果在JAVA中发生了如下代码的赋值方式,那么整个就是浅拷贝,即arrayB数组修改数组中的元素值之后会影响arrayA中的数组的元素值。
int[] arrayA = new int[3]; System.out.println(arrayA); // 地址值 System.out.println(arrayA[0]); // 0 System.out.println(arrayA[1]); // 0 System.out.println(arrayA[2]); // 0 System.out.println("=============="); arrayA[1] = 10; arrayA[2] = 20; System.out.println(arrayA); // 地址值 System.out.println(arrayA[0]); // 0 System.out.println(arrayA[1]); // 10 System.out.println(arrayA[2]); // 20 System.out.println("=============="); // 特别注意这个地方 // 将arrayA数组的地址值,赋值给arrayB数组 int[] arrayB = arrayA; System.out.println(arrayB); // 地址值 System.out.println(arrayB[0]); // 0 System.out.println(arrayB[1]); // 10 System.out.println(arrayB[2]); // 20 System.out.println("=============="); arrayB[1] = 100; arrayB[2] = 200; System.out.println(arrayB); // 地址值 System.out.println(arrayB[0]); // 0 System.out.println(arrayB[1]); // 100 System.out.println(arrayB[2]); // 200 }
- 内存示例图
7. 数组越界的异常信息
-
示例代码
// 数据类型[] 数组名称 = new 数据类型[数组长度]; // 定义一个int类型的数组,可以存放10个数据 int[] arrayA = new int[10]; // 给创建的数组赋值 for (int i = 0; i < 10; i ++){ arrayA[i] = i; } // 想要定义下标为10的对应元素值,但是数组的最大长度只是9, // 因为数组的下标是从0开始的,虽然在编译器不会报错, // 但是在运行期会直接抛出数组越界异常信息。 System.out.println(arrayA[10]);
- 异常信息截图
- 异常信息截图
8. 数组中的空指针异常
int[] arrayA = null;
System.out.println(arrayA[0]);
9. 获取数组的长度
// 数据类型[] 数组名称 = new 数据类型[数组长度];
// 定义一个int类型的数组,可以存放10个数据
int[] arrayA = new int[10];
// length可以获取数组的长度
System.out.println(arrayA.length);