跳到主要内容Java 数组基础:定义、初始化与常用方法 | 极客日志Javajava算法
Java 数组基础:定义、初始化与常用方法
Java 数组是存储同类型数据的集合,支持动态与静态初始化。本文涵盖 JVM 内存分布中数组的引用类型特性及堆栈管理,解析 null 值含义与空指针异常场景。介绍数组作为方法返回值的使用,以及 Arrays 类提供的常用工具方法,包括转字符串、拷贝、二分查找、比较与填充。最后讲解二维数组的定义、不规则数组处理及遍历打印方式。
FrontendX0 浏览 一。数组的定义与使用
数组是用来存放相同数据类型的一个集合。
1。创建数组
类型 [] 数组名 = new 类型 [n];
如:
int[] arr = new int[5];
2。数组的初始化
- 动态初始化
需要指定数组元素个数。
类型 [] 名字 = new 类型 [n]
| 数据类型 | 默认值 |
|---|
| 整型类型:byte, short, int, long | 0 |
| float | 0.0f |
| double | 0.0 |
| char | \u0000 |
| boolean | false |
如:
int[] arr = new int[5];
boolean[] boolArr = new boolean[5];
- 静态初始化
不能 指定数组元素个数,根据初始化内容决定个数。
int[] arr = new int[]{1, 2, 3, 4, 5};
3。分步初始化
先定义数组,之后再为数组初始化。
[] arr;
arr = [];
arr = []{, , };
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
int
new
int
3
new
int
1
2
3
4。求数组长度
int[] arr = {1, 2, 3, 4, 5};
int r = arr.length;
5。打印数组
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
for (int x : arr) {
System.out.print(x + " ");
}
该循环用于遍历数组,x 接收当前元素,类型需与数组元素一致。
String str = Arrays.toString(arr);
System.out.println(str);
二。引用类型和 JVM 的内存分布
1。引用类型
引用类型是用来存放地址的,数组就是引用类型,数组名是引用变量,存放了它所指向元素的首元素地址。
2。JVM 对内存的划分
JVM 翻译过来就是 Java 虚拟机,功能是划分计算机内存,便于管理和维护。
虚拟机栈:主要存储局部变量 (局部变量就是在方法内部定义的变量),当方法被执行时会在此空间开辟一块内存,方法运行结束后,会销毁开辟的空间。
堆:JVM 所管理的最大内存区,使用 new 创建的对象都是存储在堆区的,堆随着程序的开始而创建,程序的结束而销毁。
3。对数组名存储地址的理解
public static void main(String[] args) {
int a = 1;
int b = 2;
int[] arr = new int[]{1, 2, 3};
}
public static void func() {
int[] array1 = new int[3];
array1[0] = 10;
array1[1] = 20;
array1[2] = 30;
int[] array2 = new int[]{1, 2, 3, 4, 5};
array2[0] = 100;
array2[1] = 200;
array1 = array2;
array1[2] = 300;
array1[3] = 400;
array2[4] = 500;
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i] + " ");
}
}
图中 array1 数组最初指向自己本身创建的对象,元素分别是 10, 20, 30;array2 数组也是如此,元素分别是 100, 200, 3, 4, 5;看第 11 行代码 array1 = array2; 执行这一行的意思就是将 array2 数组存放的地址赋值给 array1,因此 array1 数组指向了地址为 0x8023 这个对象,而地址为 0x2233 这个对象则会被 JVM 自动回收,原因就是没有引用指向它了,所以第 12, 13, 14 行代码操作的数组其实是 array2,而不是 array1。最终输出 100 200 300 400 500
- 练习:调用 test1() 方法和 test2() 方法后,array 数组分别打印出什么?
public static void test1(int[] array) {
array[0] = 99;
}
public static void test2(int[] array) {
array = new int[]{100, 200, 300};
}
public static void main(String[] args) {
int[] array = {1, 2, 3};
test1(array);
test2(array);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
调用 test1() 方法后打印出 99 2 3
调用 test2() 方法后打印出 1 2 3
三。对 null 的认识
public static void main(String[] args) {
int[] arr = null;
System.out.println(arr.length);
}
- 给数组赋 null 值是什么意思?意思就是该数组不指向任何对象,切忌不能理解成数组指向了一个空对象。
- 什么时候给数组赋 null 值?当我们需要创建一个数组,但不知道初始化什么的时候就可以使用。
给数组赋 null 值后,如果再次操作数组的话会报错—NullPointerException 空指针异常。
四。数组的使用场景
1。数组做方法的返回值
当我们的方法需要返回多个值的时候,我们就可以返回一个数组。
public static int[] backValue() {
int a = 10;
int b = 20;
int[] array = new int[]{a, b};
return array;
}
public static void main(String[] args) {
System.out.println(Arrays.toString(backValue()));
}
上述代码创建数组时使用了变量当作数组元素,这是可行的。
五。数组常用方法
以下数组常用方法均在 java.util.Arrays 类里面,使用前需要导包。
1。数组转字符串
2。数组拷贝
Arrays.copyOf(参数 1,参数 2);
参数 1 -> 需要拷贝的数组
参数 2 -> 需要拷贝的长度,可以小于拷贝数组,从第一个元素开始
int[] array = {1, 2, 3, 4, 5};
int[] newArray = Arrays.copyOf(array, array.length);
int[] newArray2 = Arrays.copyOf(array, 3);
Arrays.copyOfRange(参数 1,参数 2,参数 3);
参数 1 -> 需要拷贝的数组
参数 2 -> 拷贝数组的起始下标 (包含)
参数 3 -> 拷贝数组的终止下标 (不包含)
包含了起始下标但不含终止下标,即 [起始下标,终止下标)
int[] array = {1, 2, 3, 4, 5};
int[] newArray = Arrays.copyOfRange(array, 1, 4);
System.arraycopy(参数 1,参数 2,参数 3,参数 4,参数 5)
参数 1 -> 需要拷贝的数组
参数 2 -> 拷贝数组的起始下标
参数 3 -> 用于接收的数组
参数 4 -> 接收数组的起始下标 (即从哪里开始存放)
参数 5 -> 需要拷贝的长度
int[] array = {1, 2, 3, 4, 5};
int[] newArray = new int[array.length];
System.arraycopy(array, 0, newArray, 0, 5);
System.arraycopy(array, 2, newArray, 1, 3);
3。二分查找数组中的元素
Arrays.binarySearch(参数 1,参数 2)
参数 1 -> 需要查找的数组
参数 2 -> 需要查找的元素
返回值:若在数组中找到该元素,则返回该元素所在下标;若没有找到,则返回负数索引
应用前提:数组必须是有序的,可以使用 Arrays.sort(array);
int[] array = {2, 7, 4, 5, 0, 6};
Arrays.sort(array);
Arrays.binarySearch(array, 4);
Arrays.binarySearch(array, 9);
4。比较两个数组
Arrays.equals(数组 1,数组 2);
返回值:若两个数组分别对应下标的元素相等,则返回 true;否则,返回 false。
int[] array1 = {1, 2, 3, 4};
int[] array2 = {1, 2, 3, 4};
int[] array3 = {1, 2, 3, 5};
Arrays.equals(array1, array2);
Arrays.equals(array1, array3);
5。修改数组中的值
Arrays.fill(参数 1,参数 2,参数 3,参数 4);
参数 1 -> 需要修改的数组
参数 2 -> 起始下标 (包含)
参数 3 -> 终止下标 (不包含)
参数 4 -> 用什么值修改
int[] array = {1, 2, 3, 4, 5, 6};
Arrays.fill(array, 1, 5, 99);
六。二维数组
1。定义一个二维数组
int[][] array = new int[2][3];
int[][] array = new int[][]{{1, 2, 3}, {4, 5, 6}};
int[][] array = {{1, 2, 3}, {4, 5, 6}};
可以将二维数组理解成一个数组里面装了多个数组,这也就是为什么二维数组的元素是{}里面还有多个{}。
2。对二维数组的认识
int[][] array = {{1, 2, 3}, {4, 5, 6}};
由图可以知道:二维数组 array 存放了两个一维数组,分别是 array[0] 和 array[1],array[0] 指向了地址为 0x6767 这个对象,array[1] 指向了地址为 0x2323 这个对象。所以 array.length 的值为 2,因为它存放了 2 个一维数组,而 array[0].length 的值为 3,因为 array[0] 是个一维数组,它存放了 3 个元素。
3。二维数组的打印
int[][] array = {{1, 2, 3}, {4, 5, 6}};
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j] + " ");
}
System.out.println();
}
理解了二维数组后,那么在打印二维数组的时候外层循环的终止条件就可以写成 array.length,内层循环终止条件则是 array[i].length
- 使用 Arrays.deepToString() 方法
int[][] array = {{1, 2, 3}, {4, 5, 6}};
System.out.println(Arrays.deepToString(array));
4。不规则二维数组
int[][] array = new int[2][];
array[0] = {1, 2, 3};
array[1] = {4, 5, 6, 7};
int[][] array = {{1, 2, 3}, {4, 5, 6, 7}};