- 数组是一种引用数据类型,数组中的元素可以是任何数据类型【包括基本数据类型和引用数据类型】。
- Java中的容器:数组、集合框架。----是在内存中对多个数据的存储,而非磁盘上。
- 声明1:double[ ]= prices; 静态初始化【数组变量的赋值和数组元素的赋值同时操作】:prices =new double[ ] {20,32,43};
- 声明2:String[ ] =foods; 初始化:动态初始化:foods= new String[4]; //4代表数组的长度。
- 其他方式:上面的可以写成一行即,int[ ] arr = new int[4]。 int arr[ ] =new int[4];int[ ] arr ={1,2,3,4}。都是正确的。
- 数组的长度:foods.length。
- 数组的调用:foods[0],foods[1]。
- 数组一旦初始化,其长度就是确定的。!!!和数组扩容有关。
- 数组元素默认值
- 一维数组内存解析
- 一般,将内存区域划分为5个:程序计数器、虚拟机栈、本地方法栈、堆、方法区。
- 与数组相关的内存结构:虚拟机栈+堆。
- 例如,int[ ] arr = new int[ ] {1,2,3}。虚拟机栈:存放方法中声明的局部变量【实际是首地址】。比如 arr。堆:存放数组实体(即数组所有元素)。比如,1,2,3。
- 只要出现new,堆中就会新开辟一块。
- 若只是int[ ] arr1 = arr。相当于只是把arr的首地址赋值给arr1,并不会再在堆中新开辟一块,本质上是同一个数组。具体如下图。
- 程序执行流程
Q:为什么数组下标从0开始?
因为第一个元素距离数组首地址间隔0个单元格。下标表示的其实是偏移量。
-
二维数组
- 声明和初始化:静态初始化,int [ ][ ] arr2 =new int[ ][ ]{{1,2,3},{4,5,6},{7,8,9,10}};动态初始化1,int [ ][ ] arr3 =new int[3][4]; 动态初始化2:int [ ][ ] arr4=new int[3][ ]。
- 其它正确的写法:一、int arr5[ ][ ] =new int [ ][ ]{{1,2,3},{4,5,6},{7,8,9}}; 二、int [ ] arr6[ ] =new int[ ][ ] {{1,2,3},{4,5,6},{7,8,9}}; 三、int arr7={{1,2,3},{4,5,6},{7,8,9}}。
- 如果初始化是动态初始化2的方式:int [ ][ ] arr4=new int[3][ ],那列数不确定的情况下,可以每一行进行初始化,即arr4[0] =new arr4[ ]{5,5,5}或者arr4[0]=new int[3]。
- 数组元素调用:调用内层:arr2[0][0]。调用外层:arr2[0]//打印出来的是{1,2,3}的地址。
- 二维数组的长度:arr2.length=3、arr2[2].length=4。
- 如何遍历数组?以arr2举例。
for(int i=0; i<arr2.length; i++){
for(int j=0; j<arr2[i].length; j++){
System.out.print(arr2[i][j] + " ");
}
System.out.println();
}
- 二维数组默认初始化值
- 以动态初始化1为根据:外层元素默认值arr3[0]:默认存储地址值(也包括了类型)。内层元素默认值:不同数据类型同一维。具体可看上面表格。
- 以动态初始化2为根据:外层元素默认值:null(因为数组也属于引用类型)。内层元素默认值:数组元素不存在,报空指针异常。
- 二维数组内存解析
打叉的会被GC回收!
- 数组之间的赋值
- 数组之间相互赋值必须满足:维数一样、类型一样。二维和一维之间不能单纯的赋值。
举例:声明:int[] x,y[]; 在给x,y变量赋值以后,以下选项允许通过编译的是:【x是一维,y是二维】
a) x[0] = y; //no
b) y[0] = x; //yes
c) y[0][0] = x; //no
d) x[0][0] = y; //no
e) y[0][0] = x[0]; //yes
f) x = y; //no提示:
一维数组:int[] x 或者int x[]
二维数组:int[][] y 或者 int[] y[] 或者 int y[][]
- 数组的反转(拓展 数组对称)
- 此时注意反转要到什么时候结束?当交换 数组.length/2次时,停止交换。
- arr[i]和arr[arr.length-1-i]做交换。
- 数组的扩容
此部分在集合中会详细讲解。
现有数组 int[] arr = new int[]{1,2,3,4,5}; ,现将数组长度扩容1倍,并将10,20,30三个数据添加到arr数组中,如何操作?
int[] arr = new int[]{1,2,3,4,5};
//1、扩容1倍容量。
int[] newArr = new int[arr.length << 1];
//2、将原有数组元素复制到新数组中。
for(int i = 0;i < arr.length;i++){
newArr[i] = arr[i];
}
//3、将10,20,30,添加到新数组中
newArr[arr.length] = 10;
newArr[arr.length + 1] = 20;
newArr[arr.length + 2] = 30;
//4、将新的数组地址赋值给原有的数组变量。
arr=newArr;
其中步骤4、内存分析如下:
补:其中涉及到GC垃圾回收器,GC是通过指针是否存在来判定是否进行回收【可达性分析算法:判断堆空间是不是可达的,是否能被其它变量访问的,不能访问的则回收。但并不是立马就回收掉(因为GC由于回收时进行会判断指针是否存在,但有时用户程序可能还在执行中,可能会走走停停这种状态,此时若要让GC一直工作就得一直进行判断。。。不太理想。。),GC会等一等,等需要GC的时候就会回收掉。比如,又来了一块内存,但堆空间满了,这时候GC会进行回收。】。
- 数组的缩容
例如,现有数组 int[] arr={1,2,3,4,5,6,7}。现需删除数组中索引为4的元素。
不新建数组版:考虑将后面的元素赋值到它前一个。
1、将后面元素赋值到前一个
for (int i = delIndex; i < arr.length - 1; i++) {
arr[i] = arr[i + 1];
}
2、由于空余出来一个位置,将最后一个元素赋值为0.arr[arr.length - 1] = 0;
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
下一篇更新数组的查找、排序等算法操作。 嘻嘻嘻~加油,鹿小葵!