文章目录
一.数组的定义与使用
数组是用来存放相同数据类型的一个集合。
1.创建数组
java
类型[] 数组名 = new 类型[n];
如:
java
int[] arr = new int[5];
2.数组的初始化
1.动态初始化
需要指定数组元素个数。
java
类型[] 名字 = new 类型[n] //数组存放的值是根据类型来确定的默认值
| 数据类型 | 默认值 |
|---|---|
| 整型类型:byte,short,int,long | 0 |
| float | 0.0f |
| double | 0 |
| char | /u000 |
| boolean | false |
如:
java
int[] arr = new int[5]; //存放的都是0
boolean[] boolArr = new boolean[5]; //存放的都是false
2.静态初始化
不能指定数组元素个数,根据初始化内容决定个数。
java
int[] arr = new int[]{1,2,3,4,5};
可简写成:int[] arr = {1,2,3,4,5};
3.分步初始化
先定义数组,之后再为数组初始化。
java
//定义一个未初始化的int型数组
int[] arr;
arr = new int[3]; //可行
arr = new int[]{1,2,3}; //可行
arr = {1,2,3}; //不可行
4.求数组长度
使用length方法
java
int[] arr = {1,2,3,4,5};
int r = arr.length; //r的值为5就是数组长度
5.打印数组
1.循环遍历
java
for(i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
2.for each方法
java
for(int x : arr) {
System.out.print(x + " ");
}
这串代码是什么意思? 循环结束条件是打印完数组为止,x是一个变量,用于接收需要遍历的数组元素,其类型必须和数组元素类型一致,arr是需要打印的数组名,每循环一次就会按照顺序把数组中存放的元素赋值给x。
3.Arrays.toString()方法
用于将数组转换成字符串。
java
String str = Arrays.toString(arr);
System.out.println(str); // 打印出[1,2,3,4,5]的样式
二.引用类型和JVM的内存分布
1.引用类型
引用类型是用来存放地址的,数组就是引用类型,数组名是引用变量,存放了它所指向元素的首元素地址。
2.JVM对内存的划分

JVM翻译过来就是Java虚拟机,功能是划分计算机内存,便于管理和维护。
现阶段我们主要了解虚拟机栈 和堆
虚拟机栈:主要存储局部变量(局部变量就是在方法内部定义的变量),当方法被执行时会在此空间开辟一块内存,方法运行结束后,会销毁开辟的空间。
堆:JVM所管理的最大内存区,使用new创建的对象都是存储在堆区的,堆随着程序的开始而创建,程序的结束而销毁。
3.对数组名存储地址的理解
1.内存的开辟
java
public static void main(String[] args) {
int a = 1;
int b = 2;
int[] arr = new int[]{1,2,3};
}

2.以下代码输出结果是什么?
java
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; //将array2中的地址赋值给array1
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
3.练习:调用test1()方法和test2()方法后,array数组分别打印出什么?
java
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的认识
java
public static void main(String[] args) {
int[] arr = null;
System.out.println(arr.length);
}
1.给数组赋null值是什么意思?意思就是该数组不指向任何对象,切忌不能理解成数组指向了一个空对象。
2.什么时候给数组赋null值?当我们需要创建一个数组,但不知道初始化什么的时候就可以使用。
给数组赋null值后,如果再次操作数组的话会报错---NullPointerException空指针异常,如下图:

四.数组的使用场景
1.数组做方法的返回值
当我们的方法需要返回多个值的时候,我们就可以返回一个数组。
java
public static int[] backValue() {
int a = 10;
int b = 20;
int[] array = new int[]{a,b};
return array;
// return new int[]{a,b};
}
public static void main(String[] args) {
System.out.println(Arrays.toString(backValue())); //打印出[10,20]
}
上述代码创建数组时使用了变量当作数组元素,这是可行的。
五.数组常用方法
以下数组常用方法均在java.util.Arrays类里面,使用前需要导包。
1.数组转字符串
java
Arrays.toString(array);
2.数组拷贝
Arrays.copyOf(参数1,参数2);
参数1 -> 需要拷贝的数组
参数2 -> 需要拷贝的长度,可以小于拷贝数组,从第一个元素开始
java
int[] array = {1,2,3,4,5};
int[] newArray = Arrays.copyOf(array,array.length) //[1,2,3,4,5]
int[] newArray = Arrays.copyOf(array,3); // [1,2,3]
Arrays.copyOfRange(参数1,参数2,参数3);
参数1 -> 需要拷贝的数组
参数2 -> 拷贝数组的起始下标(包含)
参数3 -> 拷贝数组的终止下标(不包含)
包含了起始下标但不不含终止下标,即 [起始下标,终止下标)
java
int[] array = {1,2,3,4,5};
int[] newArray = Arrays.copyOfRange(array,1,4); //[2,3,4]
System.arrayCopy(参数1,参数2,参数3,参数4,参数5)
参数1 -> 需要拷贝的数组
参数2 -> 拷贝数组的起始下标
参数3 -> 用于接收的数组
参数4 -> 接收数组的起始下标(即从哪里开始存放)
参数5 -> 需要拷贝的长度
java
int[] array = {1,2,3,4,5};
int[] newArray = new int[array.length]; //[0,0,0,0,0]
System.arrayCopy(array,0,newArray,0,5); //[1,2,3,4,5]
System.arrayCopy(array,2,newArray,1,3); //[0,3,4,5,0]
3.二分查找数组中的元素
Arrays.binarySearch(参数1,参数2)
参数1 -> 需要查找的数组
参数2 -> 需要查找的元素
返回值:若在数组中找到该元素,则返回该元素所在下标;若没有找到,则返回-1
应用前提:数组必须是有序的,可以使用Arrays.sort(array);
java
int[] array = {2,7,4,5,0,6};
Arrays.sort(array); //[0,2,4,5,6,7]
Arrays.binarySearch(array, 4); //返回2
Arrays.binarySearch(array, 9); //返回-1
4.比较两个数组
Arrays.equals(数组1,数组2);
返回值:若两个数组分别对应下标的元素相等,则返回true;否则,返回false。
java
int[] array1 = {1,2,3,4};
int[] array2 = {1,2,3,4};
int[] array3 = {1,2,3,5};
Arrays.equals(array1, array2); //true
Arrays.equals(array1, array3); //false
5.修改数组中的值
Arrays.fill(参数1,参数2,参数3,参数4);
参数1 -> 需要修改的数组
参数2 -> 起始下标(包含)
参数3 -> 终止下标(不包含)
参数4 -> 用什么值修改
java
int[] array = {1,2,3,4,5,6};
Arrays.fill(array, 1, 5, 99);
//修改后的数组为[1,99,99,99,99,6]
六.二维数组
1.定义一个二维数组
java
int[][] array = new int[2][3]; //定义了一个2行3列且所有元素都为0的二维数组
int[][] array = new int[][]{{1,2,3},{4,5,6}}; //定义了一个第1行元素为1,2,3;第2行元素为4,5,6的二维数组
int[][] array = {{1,2,3},{4,5,6}}; //等价与上一行代码
可以将二维数组理解成一个数组里面装了多个数组,这也就是为什么二维数组的元素是{}里面还有多个{}。
2.对二维数组的认识
java
int[][] array = {{1,2,3},{4,5,6}};
array.lenth的值是多少?
array[0].length的值又是多少?
现在画一个二维数组的理解图:

由图可以知道:二维数组array存放了两个一维数组,分别是array[0]和array[1],array[0]指向了地址为0x6767这个对象,array[1]指向了地址为0x2323这个对象。所以array.length的值为2,因为它存放了2个一维数组,而array[0].length的值为3,因为array[0]是个一维数组,它存放了3个元素。
3.二维数组的打印
1.循环遍历
java
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
2.使用Arrays.deepToString()方法
java
int[][] array = {{1,2,3},{4,5,6}};
System.out.println(Arrays.deepToString(array)); //[[1, 2, 3], [4, 5, 6]]
4.不规则二维数组
不规则二维数组指每一行的列数不相同。
那该如何定义一个不规则二维数组呢?
java
int[][] array = new int[2][]; //不指定列数
array[0] = {1,2,3};
array[1] = {4,5,6,7};
java
int[][] array = {{1,2,3},{4,5,6,7}};