目录
数组的由来
数组的定义
数组的特点
数组初始化
动态初始化
动态初始化内存示意图
静态初始化
数组初始化方式的使用建议
访问数组
数组访问时两个常见的小问题
数组遍历
数组在方法中的作用
数组扩容
JNI技术了解
二维数组
动态初始化
静态初始化
二维数组遍历
假如说一个班有一百个学生,每个变量只能存储一个数据,那么记录每个学生的成绩就要一百个变量,显得太麻烦,所以产生了数组
数组:存储同一种数据类型的多个元素的容器。
1. 数组是一种引用数据类型
2. 数组当中的多个数据,类型必须统一
3. 数组的长度在程序运行期间不可改变
为数组开辟内存空间,并为数组中的每个元素赋予初始默认值
概念:指定数组长度,由系统给出初始默认值,再给数组元素赋值
如果是整数类型,那么默认为0;
如果是浮点类型,那么默认为0.0;
如果是字符类型,那么默认为'\u0000';(\u表示unicode字符集,而0000是16进制)
如果是布尔类型,那么默认为false;
如果是引用类型,那么默认为null。
格式:数据类型[] 数组名 = new 数据类型[数组长度]
举例:
int[] arr = new int[3];
左边:
int:说明数组中的元素的数据类型是int类型
[]:说明这是一个数组
arr:是数组的名称
右边:
new:为数组分配内存空间
int:说明数组中的元素的数据类型是int类型,与左边数据类型保持一致
[]:说明这是一个数组
3:数组的长度,其实就是数组中能保存的元素个数
概念:定义数组的同时就给数组所有元素赋值,数组长度由初始化的元素个数决定
静态初始化的格式:
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...};
简化格式:
数据类型[] 数组名 = {元素1,元素2,...};
举例:
int[] arr = new int[]{1,2,3};
简化后:
int[] arr = {1,2,3};
注意事项:静态初始化其实也有默认值的过程,只不过系统自动马上将默认值替换成为了大括号当中的具体数值
如果不确定数组当中的具体内容,用动态初始化,否则,已经确定了具体的内容,用静态初始化比较好
数组访问格式:数组名[索引值] 索引值就是一个int数字,从0开始,一直到‘数组的长度-1’为止
如果直接打印数组名称,得到的是数组对应的内存地址哈希值
A:java.lang.ArrayIndexOutOfBoundsException
数组越界异常
产生的原因:就是你访问了数组元素,但是索引并不存在。
B:java.lang.NullPointerException
空指针异常
产生的原因:数组已经不指向堆内存的数据(对象)了,你还使用数组名去访问元素
数组提供了一个length属性,用于获取数组元素个数(数组长度)
格式:数组名.length
举例:
int[] arr = { 11, 22, 33, 44, 55 };
for(int x=0; x<arr.length; x++) {
System.out.println(arr[x]);
}
数组在方法中可以充当形式参数或者是返回值类型,传递的时候传递的其实是数组的地址值,如果是对象也是同理,之后根据地址值找到堆内存中对应的具体对象数据
举例:
先是为main方法分配栈空间,在main方法中创建data,data指向堆中创建的数组的引用0x2310,之后printArray方法进栈,分配栈空间,把data的引用0x2310给形参array,这时形参array和实参data引用了堆中同一个数组,所以在方法体中对形参数组的元素进行操作,实际上就是操作实参数组的元素,后面那个将数组当做返回值的也是同理,产生一个array数组,然后把array数组的引用赋值给another变量名,当getArray方法执行完毕,方法弹栈,但是0x4026数组有another去引用它,堆内存的数组不会被垃圾回收
数组扩容就是定义更大的数组,把原来数组的内容复制到新数组中,让原来的数组名指向新的数组
int [] data = {3,56,78,89,54,32,12}; 1.定义更大的数组 //int [] another = new int[data.length + 1] ;新数组的长度可以根据实际情况增加具体的值 // int [] another = new int[data.length * 2]; //新数组的长度经常是原来长度的2倍 int [] another = new int[data.length + data.length / 2]; //新数组的长度经常是原来长度的1.5倍 2.把原数组的内容复制到新数组中 for (int i = 0; i < data.length; i++) { another[i] = data[i]; } 3.让原来的数组名指向新的数组 data = another;在第二步将数组的内容复制到新数组中也可以采用另外一种方法:
System.arraycopy(src源数组, srcPos起始位置, dest目标数组, destPos目标数组的起始位置, length复制元素的个数); 可以把src源数组从srcPos开始的length个元素复制到dest目标数组的destPos开始的位置上
System.arraycopy(data, 0, another, 0, data.length);
该方法使用native修饰,只有方法的声明部分没有方法体, 它的方法体是由C/C++编写的, 即在Java中通过JNI技术 可以调用其他语言编写的代码
在上面数组扩容时我们使用了JNI技术,JNI技术的全称是Java native Interface -Java本地接口
我们买回来硬件是不能直接使用的,需要安装与硬件相匹配的驱动程序(操作系统可以控制硬件运作的程序就叫做驱动程序,例如主板驱动,显卡驱动),而绝大多数的驱动程序是用C语言或者C++编写的,而如果我们想要JAVA去调用驱动程序,就要使用到JNI技术,其实JNI技术就是一些接口,而接口中有方法,该方法使用native修饰,只有方法的声明,没有方法体,方法体是用C/C++编写的,即在JAVA中可以通过JNI技术去调用其他语言编写的代码
二维数组:就是元素为一维数组的数组
简单理解:使用一对方括弧就是一维数组,使用两对方括弧就是二维数组,其实本质来说没有二维数组,所有的数组都是一维数组,二维数组不过是一维数组里面存储的元素是一维数组罢了
数据类型[][] 数组名 = new 数据类型[m][n];
m表示这个二维数组有多少个一维数组,也就是二维数组长度
n表示每一个一维数组的元素有多少个
例如:int [][] towArray2 = new int[5][]
定义一个二维数组,有5个元素, 每个元素是int[]类型的,
int[]是一种引用类型, twoAray2数组的元素默认初始化为null
int [][] towArray3 = new int[5][10]
系统创建二维数组 towArray3, 有5个元素, 每个元素是int[]类型的一维数组, 在创建时,系统会给一维数组同时初始化长度为10
数据类型[][] 数组名 = new 数据类型[][]{{元素...},{元素...},{元素...},...};
简化格式:
数据类型[][] 数组名 = {{元素...},{元素...},{元素...},...};