数组
1、什么是数组
数组就是有序数据的集合,数组中的每个数据类型都是相同的。
2、数组的创建方法
数组的创建方法有两种
1.静态创建
顾名思义,静态创建就是在创建数组的时候,一开始就声名并初始化数组中的内容
注意:使用这种方法创建数组的时候,声名和初始化数组必须放在同一行
1.1、一维数组静态创建语法:
数据类型[] 数组名 = { 数组内容 };
int[] str = {1,2,3,4};
1.2、二维数组的静态创建语法:
数据类型[ ] [ ] 数组名 = {{数组内容},{数组内容},{数组内容}}
//二维数组的静态创建方法 int[][] arr = {{1,2,3},{3,4,5},{5,7}}; System.out.println(Arrays.toString(arr[2]));
2.动态创建
动态创建数组,是通过new关键字来实现对数组的创建,创建的时候只需要指定数组的长度,
对应的每个元素都有对应具体数据类型的默认值
2.1.一维数组指定数组长度动态创建语法:
数据类型[] 数组名 = new 数据类型[数组长度]
int[] str = new int[3];
在动态创建数组的时候,也可也不指定数组的长度,同时直接进行数据的初始化操作
2.2.一维数组不指定数组长度动态创建语法:
数据类型[] 数组名 = new 数据类型[]{数组内容};
int[] str = new int[]{1,2,3,4,5};
2.3、二维数组指定长度动态创建语法:
数据类型 [ ] [ ] 数组名 = new 数据类型 [ 行数] [ 列数 ];
注意:在动态创建二维数组时,可以不用再初始化时指定列数,但是一定要指定行数。
//二维数组动态创建语法
int[][] arr1 = new int[3][4];
//【3】即表示行数为3
//【4】即表示能存放4个元素
int[][] arr2 = new int[][]{{1,2,3},{2,2,3},{3,4,5}};
//定义一个只指定行数的二维数组
//说明二维数组是一个特殊的一维数组,必须制定行数,而列数可以不用在初始化时指定
int[][] arr3 = new int[3][];
//每一行相当于一个一维数组,需要创建
arr3[0] = new int[4];
arr3[1] = new int[5];
arr3[2] = new int[6];
//使用 for循环 对二维数组进行赋值
for (int i=0;i<arr3.length;i++){
for (int j=0;j<arr3[i].length;j++){
arr3[i][j] = i+j;
System.out.print(arr3[i][j]);
}
System.out.println();
}
System.out.println();
}
3、如何获取数组中的元素
在我们创建好数组后,我们要想获取数组中的元素。要通过下标来获取
注意:数组中的下标是从0开始,下标最大长度为数组长度-1
//创建一个长度为5的数组 int[] arr2 = new int[5]; /* 因为我们在上一步只创建了一个长度为5的数组,并没用为它赋值 因此在数组中只存在这int类型所对应的默认值也就是0 我们通过for循环对数组进行一个赋值 */ for(int i=0;i<arr2.length;i++){ arr2[i] = i; } /* 在这里我们已经对数组进行了一个赋值操作 他们的值分别为arr2[0]=0; arr2[1]=1;arr2[2]=2 arr2[3]=3;arr2[4]=4 */ //此时我们通过数组下标来取出对应的值即arr2[2]的值为2 System.out.println(arr2[2]); //2
4、如何修改数组中的元素
和获取数组中的元素一样,我们可以通过数组下标来对数组中的元素进行一个修改。
如下给出的例子所示,我们通过数组下标将arr2的引用变量指向一个新的堆空间中,在堆空间中存放的是我们要修改的数据。从而实现对该数组中的元素值的修改。
int[] arr2 = new int[5]; for(int i=0;i<arr2.length;i++){ arr2[i] = i; } System.out.println("修改前的arr[2]的值为 = " + arr2[2]); //修改前的arr[2]的值为 = 2 arr2[2] = 3; System.out.println("修改后的arr[2]的值为 = " + arr[2]); //修改后的arr[2]的值为 = 3
5、如何获取数组长度
我们要获取数组长度,要通过length属性来获取
注意:一旦数组的长度被创建,数组的长度就不可以改变
//获取数组中的长度 int[] arr3 = new int[10]; System.out.println("数组arr3的长度为: " + arr3.length);
6、数组的遍历
通过数组中的下标访问数组中的元素时,下标的最大值为数组长度 – 1。
否则会抛出数组下标越界异常:
ArrayIndexOutOfBoundsException(数组下标越界)
//其中j为数组中下标为0的元素 for(int j = 0;j < arrDouble.length; j++){ if(arrDouble[j] == 3.0){ arrDouble[j] = 3.1; } System.out.println(arrDouble[j]); }
7、增强for循环–foreach
语法: for(定义一个变量用来接收每一个数组元素 : 要迭代的数组) foreach循环一般只适合用来遍历数组元素的场合,其无法实现对具体某个元素做操作 int[] arr2 = new int[5]; for(int i=0;i<arr2.length;i++){ arr2[i] = i; } for(int i : arr2){ System.out.println(i); }
8、数组的内存结构
int[] arr = {1,2,3,4,5}; 在我们的 = 号左边即 int[] arr 部分,存在jvm的栈空间中,称arr为引用变量 在我们的 = 号右边即{1,2,3,4,5}部分,存在jvm的堆空间中,为真实存在的数据 我们通过 = 号将堆空间中的对象地址复制给了引用变量arr 我们通过 == 号对两个数组的引用变量进行比较,但是实际上我们比较的是两个数组的地址值 int[] arr = {1,2,3,4,5}; int[] arr1 = {1,2,3,4,5}; System.out.println(arr == arr1); //false
9、空指针异常
java空指针异常就是引用本身为空,却调用了方法,这个时候就会出现空指针异常
可以理解成成员变量早期都是属于对象的,在对象中才存在相对应的成员变量和方法,然后通过对象去调用这些成员变量和方法对于空指针来说它不指向任何对象即也就是说他没有所谓的成员变量和方法在这个时候在去调用它的某些属性和方法当然就会出现空指针异常了
public class demo { private int a=1; private int b=2; public static void main(String[] args) { demo d1 = new demo(); demo d2 = null; System.out.println(d1.a); System.out.println(d2.a); System.out.println(d2.c()); } public String c(){ return "123"; } } 我们分析上面这段示例代码,在Test类中,有两个成员变量a和b,和一个方法c()。然后在main()方法中,我们创建了两个对象d1和d2,其中d1指向通过构造方法实例出的demo对象,而d2只是声明,并指向了空,并没有指向实际的对象。调试的时候,第一条输出语句是可以通过编译的,而执行到第二条输出语句的时候,由于空指针调用了不属于它的a,程序终止,报告空指针异常。同样,注释第二条输出语句,程序在执行到第三条输出语句的时候,由于调用了不属于它的c()方法,会出现一样的错误。
10、二维数组工具类
二维数组工具类Arrays提供了众多操作数组的方法,其提供的静态方法都是通过类名.方法名调用
1.Arrays.toString(任意数组)将数组中内容以字符串的形式返回
2.Arrays.sort(任意数组)实现将数组中的数据从小到大进行排序
3.fill(数组,值):将给定的值赋值给数组中 的每个元素
4.equals(数组1,数组2):对给定两个同类型的数组进行内容的比较
//toString将数组以字符串的形式返回 int[] arr1 = new int[5]; System.out.println(Arrays.toString(arr1)); //[0, 0, 0, 0, 0] //数组排序 for(int i=0;i<arr1.length;i++){ arr1[i] = i; } arr1[0] = 10; Arrays.sort(arr1); System.out.println(Arrays.toString(arr1));//[1, 2, 3, 4, 10] //fill(数组,值) 将给定的值赋给数组中的每个元素 Arrays.fill(arr1,5); System.out.println(Arrays.toString(arr1));//[5, 5, 5, 5, 5] //equals 数组之间内容的比较 int[] arr2 = new int[]{5,5,5,5,5}; System.out.println(Arrays.equals(arr1,arr2)); //true
11、数组中的复制
1、数组的复制方式1:
System.arraycopy(源数组, 源位置, 目标数组, 目标位置, 复制长度);
源数组:提供复制数据的数组
源位置:指从源数组某个位子开始复制数据
目标数组:被添加复制的数据的数组
目标位置:指从目标数组某个位置开始起添加数组
复制长度:复制多少个数据
/* System.arraycopy(原数组,源位置,目标数组,目标位置,复制长度 源数组:提供复制数据的数组 源位置:从源数组中的某个位置开始复制数据 目标数组:被添加复制数据的数组 目标位置:指从目标数组中的某个位置开始添加数据 复制长度:指复制多少个数据 */ int[] arr1 = {2,3,4,5,6,7,8,9,10}; int[] arr2 = new int[5]; System.arraycopy(arr1,3,arr2,0,5); System.out.println(Arrays.toString(arr2));
2、数组的赋值方式2:
Arrays.copyOf(源数组,新数组长度);
//数组的复制方式2 /* Arrays.copyOf(源数组,新数组长度) */ int[] arr3 = Arrays.copyOf(arr2,3); System.out.println(Arrays.toString(arr3));
12、数组的扩容与缩容
要知道数组一旦被创建数组的长度就不可再被改变了,而我们所说的扩容或者缩容,实际上都是新建一个数组,然后将源数组中的数据复制到新数组中来,在将新数组的地址赋值给原来的引用变量。
/* 数组的扩容与缩容 在数组被创建的时候,数组的长度就已经被确定了无法在被改变 我们所说的扩容与缩容,其实指的是创建一个新的数组,然后将其 源数组中的数据复制到新数组中来,然后将新数组中的地址在复制给 原来的引用变量 */ int[] arr1 = new int[10]; for (int i=0;i<arr1.length;i++){ arr1[i] = i+1; } System.out.println(Arrays.toString(arr1)); arr1 = Arrays.copyOf(arr1,arr1.length+5); System.out.println(Arrays.toString(arr1)); arr1[14] = 10086; System.out.println(Arrays.toString(arr1));