1. 第四章数组(1课时)
1.1. 数组的基本概念
1.1.1. 什么是数组,,干嘛用的?
Java程序运算过程中,需要使用大量的数据,常见的数据形态有常量与变量。当需要一次性使用多个变量时,需要进行多次定义。为避免该现象的发生,Java语言提供了一种一次性声明创建多个变量用于存储数据机制,该机制即为数组。
简言之,数组是而为了解决一次性声明多个变量而提出的一种数据存储模型。
变量在内存中只有地址,没有名字,一次声明多个变量,这样做方便管理。
带来的好处:
1,数组中存放数据模型都相同——数据类型相同。
2,数组中存放的数据都是连续的,为每一个数据编号,JAVA中专业术语:索引(index)。日常中索引从1开始,而Array(数组)中是从0开始,这是按照西方人的思考习惯,星期天是每周开始的第一天,从0开始。
总结一下数组的基本概念:
数组是一种存放数据的容器。
数组中存放的数据的数据类型都相同。
数组具有一个固定的长度。
数组中的数据都有一个唯一的编号叫做数组元素索引或数组元素下标(index)。
数组的索引从0开始。
访问数组中的元素使用索引来访问。
创建数组的内存空间使用new关键字实现。
1.1.2. 一维数组
格式: 数据类型[] 数组名 = new 数据类型[数组长度];//数组长度即存储数据的个数
例:int[] arr=new int[10];
等号左边:声明数组
等号右边:创建内存空间(通过new关键字告诉JVM创建内存空间)
例:
int[] arr = {1,2,3};
定义int数组arr,长度为3,其中3个元素分别为1、2、3。这种方式只能在给数组类型变量赋值时使用。
int[] arr = new int[]{1,2,3};
定义int数组arr,长度为3,其中3个元素分别为1、2、3。可以在任何情况使用。
int[] arr = new int[3];
定义int数组arr,长度为3。其中所有元素都为默认值0。
数组在初始化时,对应的空间必须保证与声明时所对应的数据类型相同。
Ø 注意:
long[] errorArray=new int[10];//左边声明的类型与右边创建的格式必须绝对一致,不一致则报错!要一个long[]给一个in[],开玩笑么。
int a =10L;//注意同以前学过的变量的区别。需要一个int ,找到一个long
int[] arr=new byte[];//不兼容类型,需要一个int[]类型,找到一个byte[]类型。这里大家可以先体会下什么为什么叫类型?
double[] arr=new double[]{1,2L,3F,4D};//使用简化格式对数组进行初始化时,数组中的元素必须匹配数组的类型(兼容)
匹配过程:首先在内存中创建一个double型的数组,然后把1,2L,3F转换成double型,再放入double[]中。
int[] arr=new int[5]{1,2,412,31};//错误。创建数组时如果对其初始化,不要对数组元素总数进行指定。要么初始化,要么指定长度。
而且,注意一点,一维数组中可以使用变量
byte b=2;
int[] arr={1,4,b,1,2,5};
1.1.3. 一维数组数据读写
数组是包含了一系列相同类型数据的容器,我们通过数组名和索引就可以操作其中每一个元素。
例:
int[] arr=new int[10];//声明一个数组元素数量为10,类型为int的数组 arr
arr[1] = 100; // 给数组中索引为1的元素赋值为100
System.out.println(arr[1]); // 打印数组中索引为1的元素,结果100
获取数组的长度
数组名.length 例:arr.length;
1.1.4. 使用数组时的异常
如果访问数组时索引越界(小于0或者大于length-1),会抛出异常:ArrayIndexOutOfBoundsExcepion(数组越界异常)
如果访问数组的引用为空(null),会抛出空指针异常:NullPointerException
1.1.5. 数组元素的默认值
数组中的元素在数组初始化(new)时已经为其分配了值,其值是二进制位表示形式中对应全部为0的表示形式。
一个数组在初始化后有才有默认值。基本数据类型的默认值都是null。
整型初始值全部为0
实型初始值全部为0.0
布尔型初始值全部为false(注意,boolean型数据二进制形式全部为0,是false)
字符型初始值全部为\u0000对应的空字符。对应unicode码表中的空格。
其他类型初始值全部为null 。
例:String[] ss= new String[8]; S.o.p(ss[0]);//打印null
1.1.6. 数组的遍历(Traversal)
数组元素的遍历即对数组中所有的元素逐一访问。基于数组的索引特性,可以使用循环的形式对数组中的元素进行逐一访问。
遍历数组时,获取数组的元素总数可以使用length来获取。
具体格式:
int[] arr=new int[10];//数组长度值不可修改,在数组初始化阶段已经设置完成
System.out.println(arr.length);//打印数组长度,length有一个范围,而且是有限个,最大个数:Integer.MAX_VALUE
for(int i=0;i<10;i++){System.out.println(a[i]);}
1.1.7. 用数组思想解决问题
面试题一:
//养兔子、斐波那契数列问题
//1.求斐波那契数列第n项的值
//2.打印斐波那契数列前n项的值
//3.求印斐波那契数列前n项的和
分析:
第一项+第二项 = 第三项
第N项+第N+1项= 第N+2项
第N-2项+第N-1项= 第N项
、 //斐波那契数列前两项的值是1
int n = 10;
//创建一个数组用于存放斐波那契数列的前N项
long[] fibs = new long[n];
fibs[0] = 1;
fibs[1] = 1;
int sum = 0;
for(int i = 2;i<=fibs.length -1 ;i++){
fibs[i] = fibs[i-1]+fibs[i-2];
sum+=fibs[i];
}
for(int i=0;i<fibs.length;i++){
System.out.println(fibs[i]);
}
System.out.println("sum="+sum);
//求第n项斐波那契数列的值
int a = 1;
int b = 1;
int n = 4;
int c = -1;
for(int i = 3;i<=n;i++){
//求第X项
c = a + b;
//为了下一轮求X+1项,必须将a,b的变化为去x+1项所使用的数据
a = b;
b = c;
}
System.out.println("第"+n+"项的值是:"+c);
//用变量来做:
int a = 1;
int b = 1;
int n = 10;
int c = -1;
int sum = 0;
for(int i = 1;i<=n;i++){
if(i == 1 || i == 2){
sum+=1;
}else{
//求第X项
c = a + b;
//为了下一轮求X+1项,必须将a,b的变化为去x+1项所使用的数据
a = b;
b = c;
sum+=c;
}
}
System.out.println(sum);
*/
/*
int a = 1;
String s = "123";
int[] arr = {1,2,3};
String[] ss = {"aa","bb","cc"};
for(int i = 0;i<ss.length;i++){
System.out.println(ss[i]);
}
*/
1.1.8. 二维数组(不用到作为了解)
二维数组可以看做是一种特殊的一维数组,即第一维数组中的数组元素全部是一维数组。
二维数组中保存的一维数组必须结构相同,即保存的数组存储的数据类型必须完全相同
二维数组中无须保障其中保存的一维数组长度都是相同的。
二维数组的长度仅仅表明其中保存的一维数组的数量,并不能约束其中保存的一维数组的长度。
可以理解为组合柜与抽屉的关系。
int[][] arr;// 第一个[]存地址,第二个[]存数据
arr=new int[10][];//new告诉JVM创建内存空间,[10]定义数组的个数。
二维数组的五种定义格式(重点是第五种)
格式1:
数据类型[][] 数组名 ;
int[][] arr ; double[][] arr1;
boolean[] arr2 []; long arr3 [] [];
格式2:
数据类型[] [] 数组名 = new 数据类型[长度] [长度];
int[][] arr = new int[4][5];
double [][] arr1 = new double[5][10];
long[][] errorArray = new int[10][20];
格式3:
数据类型[][] 数组名 = new 数据类型[][]{{数组元素列表1},{数组元素列表2},……};
int[][] arr = new int[][]{{1,3},{7,9}};
long[][] arr1 = new long[][] {{2,4},{6L,8},{10L,12L}};
long[][] errorArray = new long[] {{3.14 , 80L}};
int[][] arr2 = new int[][]{};
int[][] arr2 = new int[][]{{},{}};
格式4:
数据类型[][] 数组名 = {{数组元素列表1}, {数组元素列表2},……}; 不能分开赋值
int[][] arr = {{1,3},{5,7}};
int[][] errorArray1 = {{1,3},5,7,{9,11}};
int[][] errorArray2 ={1,3,5,7,9};
int[][] array3 ;
array3 = {{1,3},{5,7}};
格式5:
数据类型[][] 数组名 = new 数据类型[长度][];
数组名[索引] = new 数据类型[长度];
int[][] arr=new int[3][];//定义第二维数组的个数3
arr[0]=new int[]{1,4,7};//可以直接静态初始化
arr[1]=new int[2];
arr[2]=new int[1];
先对二维数组外层数组的长度进行初始化,然后再对其中保存的数据即内层一维数组进行单独初始化
使用此格式可以创建出特殊的二维数组,即其中保存数据的一维数组长度均不相同。
此格式更有利于对现实生活中的数据进行描述。
二维数组的数据存储位置
二维数组数组中的数据均保存在第二维的数组中,因此在访问时,二维数组中每个元素均拥有两个索引值,任意两个数组元素的两个索引值不完全相同。
二维数组数据读写
数组元素的修改
格式:数组名[第一层索引] [第二层索引] = 值;
int [][] arr = new int[4][4];
arr[1][1] = 100;
数组元素的读取
格式:数组名[第一层索引] [第二层索引];
int [][] arr = new int[4][9];
System.out.println(arr[0][0]);
System.out.println(arr[10][10]);//角标越界异常
面试题:
考数组,如果不是为了让你用数组做模型存数据,就是考你格式
int [][] arr={};//可以
int [][][]][][] [][][][][][][][][][][][][]arr={};//可以
int[]arr[]={{}};//可以
int []arr[]={{},{},{}};//可以,没有问题
int[] arr={{}};//int的初始化不合法
int [][] arr=new [][]{};//错
int [][] arr= new int[4]://错
int [][] arr=new [][4];//错
int [][] arr=new [4][];//可以
二维数组总结
数据类型 变量名;
int a ; //声明一个变量 类型int a
int[] b; //声明一个数组 保存数据的类型int [] 数组名
int[][] c; //声明一个数组 保存数据的类型int[] [] c
看这个例子,体会→保存数据的类型
int[][] arr = {{1,3},{5,7}};
int[][] errorArray1 = {{1,3},5,7,{9,11}};//报错:不兼容的数据类型,保存数据的类型为int[] , 但是给出了 5,7 int型的数据。
推导得出结论》》》》》》数组是一种特殊的数据类型
数组在内存中的以“引用”的形式描述
引用即参照,即对应存储的数据指向另一个实际存储数据的区域,中间的联系使用内存地址进行
那么数组这种类型和基本数据类型区别是什么?
在内存中,基本数据类型后面保存的是值
在内存中,数组变量名后面保存的是地址
在java语言中,将这种保存地址作为值的数据称为引用型数据
扩展一:
内存标志位
int[][] arr={{12,1},{42,4},{1,5},{141,2}};
for(int i=0;i<arr.length-1;i++)
System.out.println(arr[i]);
打印结果:
[I@bb0d0d
[I@55e55f
[I@145c859
这到底是什么?
[代表这是个数组
I代表里面放的是int值
@代表分隔符
@后面的数字代表这个东西在内存中真正的内存地址
1.1.9. 数组的最值
1.1.10. 数组元素的排序
选择排序、冒泡排序。
要求学有余力的同学在毕业前掌握快排。
引入数据结构的思想。
1.1.11. 数组元素的查找
查找是对有序数组进行查找,先排序再查找。
二分法
Ø 与数组操作相关函数
Arrays.toString() 查找帮助文档Arrays类,学习使用此方法将字符串转为字符串形式。
将一个数组转为字符串表示形式
System.arraycopy() 查找帮助文档System类,学习使用此方法拷贝数组中元素。
将一个数组中的某些元素拷贝到另一个数组的指定位置
Ø 多维数组
数组中的每一个元素都是数组,这样的数组就是多维数组。
int[][] arr = { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8, 9 } };
定义二维数组arr, 其中有三个元素都是数组, 第一个数组3个元素, 第二个2个元素, 第三个4个元素.
int[][] arr = new int[][] { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8, 9 } };
定义二维数组arr, 其中有三个元素都是数组, 第一个数组3个元素, 第二个2个元素, 第三个4个元素.
int[][] arr = new int[3][3];
定义二维数组arr, 其中有三个元素都是数组, 每个小数组都是3个元素.
int[][] arr = new int[3][];
定义二维数组arr, 其中有三个元素都是数组, 每个小数组元素个数不确定.