本章节对于个人而言的新增知识点
-
数组的动态初始化,需要开辟空间
-
计算数组的长度:(数组名.length)
-
数组的常见异常:出现空指针
原因是数组需要开辟内存空间才可以存放数据或访问 -
内存的管理
方法区:存放主方法和各种方法名
堆内存:存放开辟的空间和对象
栈内存:存放的是局部变量和形参 -
数组遍历,无需for循环遍历,通过System.out.println(Arrays.toString(array));,添加相对应的工具包
-
数组的拷贝。第一种AIP的方式(需要创建新的数组):arraycopy。第二种函数(直接在原先的数组上开辟所需内存空间):Arrays.copyOf
数组的概念
数组:用于存放多个相同类型数据的容器
特点:
1. 数组是引用数据类型
2. 数组存储相同数据的类型
3. 数组的长度在运行期间不可改变
数组初始化
1. 静态初始化(内容固定)
标准格式:数据类型 [] 数组名 = new 数组类型[]{内容1,内容2,内容3};
简便格式:数据类型 [] 数组名 = {内容1,内容2,内容3};
分步骤格式:数据类型 [] 数组名;
数组名 = new 数组类型[]{内容1,内容2,内容3};
3. 动态初始化(长度固定)
标准格式:数据类型 [] 数组名 = new 数组类型[元素个数];
分步骤格式:数据类型 [] 数组名;
数组名 = new 数组类型[元素个数];
代码演示:数组初始化
public class HelloWorld {
public static void main(String[] args) {
// 定义动态数组初始化,并确认数组长度
int[] array1 = new int[10];
String[] array2 = new String[5];
// 定义静态数组初始化,数组赋值也就决定了该数组的长度
int[] array3 = new int[]{1,2,3};
String[] array4 = new String[]{"home","java","hello"};
double[] array5 = {1.2,3.6,0.7};
}
}
数组的应用
代码演示:计算数组的长度
public class HelloWorld {
public static void main(String[] args) {
String[] array = new String[]{"wzz","java","hello"};
int len = array.length;
System.out.println("数组的长度是"+len); // 运行结果:数组的长度是3
}
}
代码演示:数组遍历
通过数组的下标方式,访问索引值
public class HelloWorld {
public static void main(String[] args) {
int i;
// 静态数组遍历
String[] array = new String[]{"wzz", "java", "hello"};
int len = array.length;
for (i = 0; i < len; i++){
System.out.println(array[i]);
}
// 动态数组遍历(每个下标都要默认值)
int[] arry = new int[3];
for (i = 0; i < len; i++){
System.out.println(arry[i]);
}
}
}
代码演示:数组常见的异常
- 数组越界异常:访问数组下标越界
- 数组空指针异常:数组未开辟空间就使用(访问、计算长度等)
public class HelloWorld {
public static void main(String[] args) {
// 1. 数组下标越界
int[] array1 = {1,2,3};
// System.out.println(array1[3]);
// 系统运行报错:ArrayIndexOutOfBoundsException(数组索引越界异常)
// 2. 空指针异常
int[] array2 = null;
// System.out.println(array2[0]);
// 系统运行报错:NullPointerException(空指针异常)
// System.out.println(array2.length);
// 系统运行报错:NullPointerException(空指针异常)
}
}
内存管理
方法区:存储class文件(类信息)
堆内存:new关键字创建的对象或数组,数组在堆中以16进制地址的方式存储并每个下表都要默认值
栈内存:方法的栈帧、局部变量
数组的内存分析图
数组名作为地址
代码演示:数组名作为方法的返回值
public class HelloWorld {
public static void main(String[] args) {
int arrMain[] = method(); // 解析:arrMain与arr地址相同
System.out.println("数组第一个元素是" + arrMain[0]); // 运行结果:数组第一个元素是1
System.out.println("数组第二个元素是" + arrMain[1]); // 运行结果:数组第二个元素是2
}
public static int[] method() { // 注意:返回类型是数组类型
int arr[] = new int[2];
arr[0] = 1;
arr[1] = 2;
return arr; // 解析:返回的是arr的地址,里面包含了数组所对应下表的数值
}
}
代码演示:数组名作为方法的参数
public class HelloWorld {
public static void main(String[] args) {
int[] array = {1,2,3};
System.out.println("main:array的地址"+array); // 运行结果:main:array的地址[I@1b6d3586
run(array); // 解析:数组名通过地址的方式传递
}
public static void run(int[] arr) { // 解析:arr与array的地址相同
System.out.println("run:arr的地址"+arr); // 运行结果:run:arr的地址[I@1b6d3586
}
}
系统API与数组相关
代码演示:数组遍历
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int array[] = {1,2,3};
System.out.println(Arrays.toString(array)); // 运行结果:[1, 2, 3]
}
}
数组拷贝
问题:在堆中开辟两块的内存空间,其地址不同。将A数组的内容拷贝到B数组中
代码演示:传统数组拷贝
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int array[] = {51,32,43,12,94,26};
method(array);
}
private static void method(int arr[]) {
int len = arr.length;
int newArr[] = new int[len];
for (int i = 0; i < len; i++) {
newArr[i] = arr[i];
}
System.out.println("arr的地址:" + arr + ",newArr的地址:" + newArr);
// 运行结果:arr的地址:[I@1b6d3586,newArr的地址:[I@4554617c
//(证明:两个数组的内存空间不同)
System.out.println("新数组的元素:"+Arrays.toString(newArr));
// 新数组元素:[51, 32, 43, 12, 94, 26]
}
}
代码演示:系统API的数组拷贝
public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
解析参数列表
scr:拷贝原数组
srcPos:原数组拷贝的起始位
dest:拷贝目标数组
destPos:目标数组拷贝的起始位
int length:拷贝的长度
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int array[] = {51,32,43,12,94,26};
method(array);
}
private static void method(int arr[]) {
int newArr[] = new int[10];
System.arraycopy(arr,0,newArr,1,4);
// 解析:将arr拷贝到newArr,从arr的第0位取出4个元素拷贝到newArr的第1位开始拷贝
System.out.println(Arrays.toString(newArr));
// 运行结果:[0, 51, 32, 43, 12, 0, 0, 0, 0, 0]
}
}
数组扩容或缩容
问题:在堆中同一块内存空间,其地址相同,增加存储量。将A数组的存储空间扩大
代码演示:传统数组扩容
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int array[] = {51,32,43};
method(array);
}
private static void method(int arr[]) {
int newArray[] = new int[arr.length+2];
for(int i = 0; i < arr.length; i++) {
newArray[i] = arr[i];
}
arr = newArray; // 解析:arr 指向 newArray
System.out.println(Arrays.toString(newArray));
}
}
代码演示:系统API的数组扩容或缩减
public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
return copy;
}
original:针对某个数组
newLength:重置数组的内存空间
import java.util.Arrays;
public class Demo1 {
public static void main(String[] args) {
int array[] = {51,32,43};
method(array);
}
private static void method(int arr[]) {
int newArray[] = Arrays.copyOf(arr,arr.length+2);
newArray[3] = 56;
arr = newArray;
System.out.println(Arrays.toString(arr));
}
}