数组的概念
数组:用来存储和管理一组相同数据类型的数据。它是一种容器。
数组名:为了方便存储和管理一组相同数据类型的数据,使用一个统一的名称来管理它们。
下标:为了区别一组数组中的每一个,使用编号/索引/下标来表示
元素:这一组数据中的每一个数据是一个元素,表示方式:数组名[下标]
数组的长度:数组的元素的总个数,表示方式:数组名.length
下标的范围:[0, 数组的长度-1]
数组名:记录这一组数据在“堆”内存中的首地址。
下标从0开始:距离首地址间隔0个单元格
一维数组
1、声明的格式
元素的数据类型[] 数组名;//推荐
或
元素的数据类型 数组名[];
2、初始化方式
(1)静态初始化
元素的数据类型[] 数组名 = {元素值1,元素值2。。。。}; //如果分开两行 元素的数据类型[] 数组名; 数组名 = new 元素的数据类型[]{元素值1,元素值2。。。。};
静态初始化的方式,在创建数组对象的同时就指定了数组的元素的值,而且数组的长度由列出来的元素的个数决定。
(2)动态初始化
元素的数据类型[] 数组名 = new 元素的数据类型[长度]; //如果分开两行 元素的数据类型[] 数组名; 数组名 = new 元素的数据类型[长度];
动态初始化的方式,在我们创建完数组对象时,还没有为元素赋值的话,元素是默认值。
3、为元素赋值
数组名[下标] = 值;
arr[i] = 常量值; //常量值为元素赋值
arr[i] = (int)(Math.random()*100); //使用随机数为元素赋值
arr[i] = input.nextInt(); //从键盘输入为元素赋值
arr[i] = i*2 + 1; //使用表达式的结果为元素赋值
4、遍历
for(int i=0; i<数组的长度; i++){ //数组名[i]表示元素 }
5、数组元素的默认值
byte,short,int,long:默认值是0
float,double:默认值是0.0
char:默认值是编码值为0的字符,\u0000
boolean:默认值是false
引用数据类型:null
6、一维数组的内存分析
凡是数组,即new出来都在堆中。
数组的元素是连续存储的。
一维数组的基础算法
求和
int[] arr = {3,2,5,1,4}; int sum = 0; for(int i=0; i<arr.length; i++){ sum += arr[i]; }
求均值
int[] arr = {3,2,5,1,4}; double sum = 0; for(int i=0; i<arr.length; i++){ sum += arr[i]; } double avg = sum / arr.length;
统计偶数/奇数个数
int[] arr = {3,2,5,1,4}; int odd = 0; int even = 0; for(int i=0; i<arr.length; i++){ if(arr[i] % 2==0 ){ even++; }else{ odd++; } }
查找
顺序查找
int[] arr = {3,2,5,1,4}; int findValue = ?; int index = -1; for(int i=0; i<arr.length; i++){ if(arr[i] == findValue){ index = i; break; } } if(index==-1){ System.out.println("不存在"); }else{ System.out.println(findValue + "的下标是" + index); }
String[] names = {"张三","李四","王五"}; String findValue = ?; int index = -1; for(int i=0; i<arr.length; i++){ if(arr[i].equals(findValue)){ index = i; break; } } if(index==-1){ System.out.println("不存在"); }else{ System.out.println(findValue + "的下标是" + index); }
找最值
int[] arr = {3,2,5,1,4}; int max = arr[0];//假设第一个最大 //和后面的元素一一比较 for(int i=1; i<arr.length; i++){ if(arr[i] > max){ max = arr[i]; } }
找最值下标
int[] arr = {3,2,5,1,4}; int max = arr[0];//假设第一个最大 int index = 0; //和后面的元素一一比较 for(int i=1; i<arr.length; i++){ if(arr[i] > max){ max = arr[i]; index = i; } }
int[] arr = {3,2,5,1,4}; int index = 0;//假设第一个最大 //和后面的元素一一比较 for(int i=1; i<arr.length; i++){ if(arr[i] > arr[index]){ index = i; } } System.out.println("最大值是:" + arr[index]);
排序
冒泡排序:
结果:从小到大排序
(1)从左边开始把大的往右边移动
int[] arr = {3,2,5,1,4}; for(int i=1; i<arr.length; i++){ /* 因为每一轮从最左边开始,int j=0;起始值 i=1, j=0,1,2,3 i=2, j=0,1,2 i=3, j=0,1 i=4, j=0 j<arr.length-i */ for(int j=0; j<arr.length-i ; j++){ //前面的元素 > 后面的元素 /* 前后元素:arr[j]与[j+1] 前后元素:arr[j-1]与arr[j] 因为我这里j=0开始,arr[j-1]当j=0的时候会越界 */ if(arr[j] > arr[j+1]){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } }
(2)从右边开始把小的往左边移动
int[] arr = {3,2,5,1,4}; for(int i=1; i<arr.length; i++){ /* 因为从右边开始把小的往左边移动,所以j的起始点 arr.length-1 i=1, j=4,3,2,1 i=2, j=4,3,2 i=3, j=4,3 i=4, j=4 int j = arr.length-1; j>=i; j-- */ for(int j=arr.length-1; j>=i; j--){ //右边的元素 < 左边的元素 交换 /* 右边与左边元素:arr[j]与[j-1] 右边与左边元素:arr[j+1]与arr[j] 因为j的起始点arr.length-1,[j+1]会导致越界 */ if(arr[j] < arr[j-1]){ int temp = arr[j]; arr[j] = arr[j-1]; arr[j-1] = temp; } } }
二维数组
1、声明格式
数组的元素类型[][] 数组名;//推荐写法
或
数组的元素类型 数组名[][];
或
数组的元素类型[] 数组名[];
class Test04Review4{ public static void main(String[] args){ //标准声明二维数组的方式 int[][] arr1 = new int[3][]; //其他的方式 int arr2[][] = new int[3][]; int[] arr3[] = new int[3][]; System.out.println(arr1);//[[I@15db9742 System.out.println(arr2);//[[I@6d06d69c System.out.println(arr3);//[[I@7852e922 //面试题 int[] x, y[]; //答案:x是一维数组,y是二维数组 //x = new int[2][];//错误,因为x是一维数组 //y = new int[3];//错误的,一维y是二维数组 } }
2、初始化
(1)静态初始化
数组的元素类型[][] 数组名 = {{第一行的元素} , {第二行的元素} 。。。}; //分开两行代码 数组的元素类型[][] 数组名; 数组名 = new 数组的元素类型[][]{{第一行的元素} , {第二行的元素} 。。。};
(2)动态初始化:每一行的列数可能不同
数组的元素类型[][] 数组名 = new 数组的元素类型[总行数][]; //单独指定每一行的列数 数组名[行下标] = new 元素的类型[列数];//每一行是一个一维数组
(3)动态初始化:每一行的列数相同
数组的元素类型[][] 数组名 = new 数组的元素类型[总行数][列数];
3、遍历
二维数组的长度,二维数组的总行数:数组名.length
二维数组的某一行:数组名[行下标]
二维数组的某一行的列数,某一行的长度:数组名[行下标].length
行下标的范围:[0, 数组名.length-1]
二维数组的某个元素:数组名[行下标][列下标]
列下标的范围:[0, 数组名[行下标].length-1 ]
for(int i=0; i<数组名.length; i++){ for(int j=0; j<数组名[i].length; j++){ //元素:数组名[i][j] } }
在数组使用过程中经常遇到的两种异常
1、数组下标越界异常:ArrayIndexOutOfBoundsException
一维数组的下标范围:[0, 数组名.length-1]
二维数组的行下标范围:[0, 数组名.length-1]
二维数组的列下标范围:[0, 数组名[行下标].length -1]
2、空指针异常:NullPointerExeption
元素是引用数据类型:
例如:String[],Student[]...
这种数组的元素的默认值是null,在给元素赋值之前,使用数组的元素进行.操作就会报空指针异常
String[] names = new String[3]; System.out.println(names[0].charAt(0));//names[0]是null
使用二维数组时,如果没有为行指定列数,那么此时行是null
int[][] arr = new int[3][]; System.out.println(arr[0].length);//arr[0]是null System.out.println(arr[0][0]);//arr[0]是null