1.概念:一组连续的存储空间,可以同时存储多个相同类型的数据,并且可以统一操作。
2.数组的要素
(1) 数组的长度:决定了数组可以存储多少个数据
(2) 数组的数据类型:决定数组可以存储哪种类型的数据
3.数组的声明
(1) 先声明:数据类型[] 数组名;
int[] a; // 建议
int []a;
int a[];
(2) 再分配空间:确定数组的长度
数组名 = new 数据类型[长度];
a = new int[5];
4.注意事项
(1) 数组的下标,从0开始,依次为0,1,2,3....
(2) 数组的最大下标为:数组的长度 -1
(3) 数组的访问:数组名+下标,
赋值:数组名[下标] = 值;
访问:数组名[下标]
(4) 访问数组时,超过下标范围,则编译通过,运行报错,错误信息为: java.lang.ArrayIndexOutOfBoundsException(数组下标越界)
(5) 数组的遍历:将数组中元素进行一一访问的过程
// 使用 循环控制 数组的下标
for(int i=0;i<数组长度; i++){
// 通过数组名 + 下标 i操作数组 -> a[i]
System.out.println(a[i]);
}
(6) 获取数组的长度:数组名.length
为了提高代码的灵活性,将遍历使用length获取长度:
for(int i=0;i<数组名.length;i++){}
(7) 数组具有默认值,默认值情况如下:
整数类型:0
小数类型:0.0
字符类型:空字符('\u0000')
布尔类型:false
引用类型:null
5.其他定义方式
(1) 先声明,再分配空间:
数据类型[] 数组名;
数组名 = new 数据类型[长度];
int[] a;
a = new int[4];
(2) 声明的同时,分配空间:
数据类型[] 数组名 = new 数据类型[长度];
int[] a = new int[3];
(3) 声明的同时初始化:
数据类型[] 数组名 = new 数据类型[]{数据1,数据2,数组3};
注意:{}中的个数决定了数组长度。数组的长度不在[]中指定
int[] a = new int[]{3,7,5};
(4) 声明的同时并初始化:
数据类型[] 数组名 = {数据1,数据2,数据3};
注意:初始化必须和声明一起完成
int[] a;
a = {3,6}; // 错误的写法
6.数组的内存
1.数组在内存中的空间是连续的
2.数组变量存储的数组在空间中首地址
3.计算的寻址公式:首地址+数据类型的字节数*下标
7.扩容
思想:
(1) 申请一个更大长度空间的数组,通常是原来长度的2倍
(2) 将原数组中数据,一一赋值到新的数组中
(3) 新数组地址覆盖 旧地址
实现:
第一种方式:
// 存储 5学生年龄
int[] ages = new int[5];
ages[0] = 23;
ages[1] = 21;
ages[2] = 25;
ages[3] = 28;
ages[4] = 18;
// ....
// ....
System.out.println("-------------");
// 又来一个学生,存储该生年龄:ages
// 扩容
// 1. 定义一个更大长度的新数组
int[] b = new int[ages.length*2]; // 10
// 2. 将源数组中内容一一赋值到新数组中
for(int i = 0 ;i<ages.length;i++){
// 新数组 = 原数组
b[i] = ages[i]; // b[0] = ages[0]
}
// 3. 新地址 覆盖旧地址
ages = b;
for(int i=0;i< ages.length;i++){
System.out.println(ages[i]);
}
第二种方式:借助工具类完成数组的扩容
java.util.Arrays.copyOf(原数组名,新数组的长度);
// 存储 5学生年龄
int[] ages = new int[5];
ages[0] = 23;
ages[1] = 21;
ages[2] = 25;
ages[3] = 28;
ages[4] = 18;
// ....
// ....
System.out.println("-------------");
// 又来一个学生,存储该生年龄:ages
// 扩容
ages= Arrays.copyOf(ages,ages.length*2);
for(int i=0;i< ages.length;i++){
System.out.println(ages[i]);
}