数组的概述
- 数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
- 数组的常见概念
- 数组名
- 下标(或索引)
- 元素
- 数组的长度
- 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
- 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
- 数组的长度一旦确定,就不能修改。
- 我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
- 数组的分类:
- 按照维度:一维数组、二维数组、三维数组、…
- 按照元素的数据类型分:基本数据类型元素的数组、引用数据类型元素的数组(即对象数组)
一维数组
- 一维数组的声明方式:
type var[] 或 type[] var;
例如:int a[];
int[] a1;
double b[];
String[] c; //引用类型变量数组
-
Java语言中声明数组时不能指定其长度(数组中元素的数), 例如: int a[5]; //非法
-
动态初始化:数组声明且为数组元素分配空间与赋值的操作分开进行
int[] arr = new int[3]; arr[0] = 3; arr[1] = 9; arr[2] = 8; 或 String names[]; names = new String[3]; names[0] = “钱学森”; names[1] = “邓稼先”; names[2] = “袁隆平”;
-
静态初始化:在定义数组的同时就为数组元素分配空间并赋值。
int arr[] = new int[]{ 3, 9, 8};或int[] arr = {3,9,8}; String names[] = {“李四光”,“茅以升”,“华罗庚” }
-
定义并用运算符new为之分配空间后,才可以引用数组中的每个元素;
-
数组元素的引用方式:数组名[数组元素下标]
- 数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i];
- 数组元素下标从0开始;长度为n的数组合法下标取值范围: 0 —>n-1;如int a[]=new int[3]; 可引用的数组元素为a[0]、a[1]、a[2]
-
每个数组都有一个属性length指明它的长度,例如:a.length 指明数组a的长度(元素个数)
- 数组一旦初始化,其长度是不可变的
-
数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化。例如:
int a[]= new int[5]; System.out.println(a[3]); //a[3]的默认值为0
- 对于基本数据类型而言,默认初始化值各有不同
- 对于引用数据类型而言,默认初始化值为null(注意与0不同!
数组元素类型 元素的默认初始化值 byte 0 short 0 int 0 long 0L float 0.0F double 0.0 char 0或写为'u0000'(表现为空) boolean false 引用类型 null -
Java中使用关键字new来创建数组
- 如下是创建基本数据类型元素的一维数组
int[] s; s = new int[10]; //int[] s=new int[10]; //基本数据类型数组在显式赋值之前, //Java会自动给他们赋默认值。 for ( int i=0; i<10; i++ ) { s[i] =2*i+1; System.out.println(s[i]); }
- 执行int[] s;后的内存变化
- 执行s = new int[10];后的内存变化
- 执行 s[i] =2*i+1;后的内存变化
//1.一维数组的声明和初始化
int[] ids;//声明
//1.1静态初始化:数组的初始化和元素的赋值操作同时进行
ids = new int[] {1001,1002,1003,1004};
//1.2动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
//错误的写法
//int[] arr1 = new int[];
//int[5] arr2 = new int[];
//int[] arr3 = new int[3]{1,2,3};
//总结:数组一旦初始化完成,其长度就基本确定了
//2.如何调用数组的指定位置的元素:通过下标的方式调用
//数组的下标(或索引)从0开始的,到数组的长度-1结束
names[0] = "zhangsan";
names[1] = "lisi";
names[2] = "wangwu";
names[3] = "liuliu";
names[4] = "zhaoyun";
//3.如何获取数组的长度。
//属性:length
System.out.println(names.length);//5
System.out.println(ids.length);//4
//4.如何遍历数组
System.out.println(names[0]);
System.out.println(names[1]);
System.out.println(names[2]);
System.out.println(names[3]);
System.out.println(names[4]);
for(int i = 0;i < names.length;i++) {
System.out.println(names[i]);
}
//5.数组元素的默认初始化值
int[] arr = new int[4];
for(int i = 0;i < arr.length;i++) {
System.out.println(arr[i]);//输出0
}
char[] arr1 = new char[4];
for(int i = 0;i < arr1.length;i++) {
System.out.println((int)arr1[i]);//0
}
多维数值
-
对于二维数组的理解,我们可以看成是一维数array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,其实没有多维数组。
-
二维数组[][]:数组中的数组。初始化方法
-
格式1(动态初始化):int[][] arr = new int[3][2];
- 定义了名称为arr的二维数组
- 二维数组中有3个一维数组
- 每一个一维数组中有2个元素
- 一维数组的名称分别为arr[0], arr[1], arr[2]
- 给第一个一维数组1脚标位赋值为78写法是:arr[0][1] = 78;
- 格式2(动态初始化):int[][] arr = new int[3][];
- 二维数组中有3个一维数组。
- 每个一维数组都是默认初始化值null (注意:区别于格式1)
- 可以对这个三个一维数组分别进行初始化
arr[0] = new int[3]; arr[1] = new int[1]; arr[2] = new int[2];
- 注:int[][] arr = new int[][3]; //非法
-
格式3(静态初始化):int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};
- 定义一个名称为arr的二维数组,二维数组中有三个一维数组
- 每一个一维数组中具体元素也都已初始化
- 第一个一维数组 arr[0] = {3,8,2};
- 第二个一维数组 arr[1] = {2,7};
- 第三个一维数组 arr[2] = {9,0,1,6};
- 第三个一维数组的长度表示方式:arr[2].length;
-
-
注意特殊写法情况:int[] x,y[]; x是一维数组,y是二维数组。
-
Java中多维数组不必都是规则矩阵形式
-
内存的解析
//1.一维数组的声明和初始化
int[] arr = new int[] {1,2,3};//一维数组
//静态初始化
int[][] arr1 = new int[][]{{1,2,3},{1,2},{1,2,3}};
//动态初始化1
String[][] arr2 = new String[3][2];
//动态初始化2
String[][] arr3 = new String[3][];
//错误的情况
//String[][] arr4 = new String[][4];
//String[4][3] arr5 = new String[][];
//int[][] arr6 = new int[4][3]{{1,2,3},{1,4,2},{1,2,3}};
//也是正确的
int[] arr4[] = new int[][]{{1,2,3},{1,2,3,4,5,6},{1,2,3}};
int[] arr5[] = {{1,2,3},{1,4,2},{1,2,3}};
//2.如何调用数组的指定位置的元素:
System.out.println(arr1[0][1]);//2
System.out.println(arr2[1][1]);//null
arr3[1] = new String[4];
System.out.println(arr3[1][0]);
//3.如何获取数组的长度
System.out.println(arr4.length);//3
System.out.println(arr4[0].length);//3
System.out.println(arr4[1].length);//6
//4.如何遍历数组
for (int i = 0; i < arr4.length; i++) {
for (int j = 0; j < arr4[i].length; j++) {
System.out.print(arr4[i][j]+" ");
}
System.out.println();
}
//5.数组元素的默认初始化值
int[][] arr9 = new int[4][3];
System.out.println(arr9);//[[I@15db9742 地址值,左边有两个[
System.out.println(arr9[0]);//[I@6d06d69c 地址值,左边有一个[
System.out.println(arr9[0][0]);//0
double[][] ar1 = new double[4][3];
System.out.println(ar1);//[[D@7852e922 地址值,左边有两个[
System.out.println(ar1[0]);//[D@4e25154f 地址值,左边有一个[
System.out.println(ar1[0][0]);//0.0
String[][] ar2 = new String[4][3];
System.out.println(ar2);//[[Ljava.lang.String;@70dea4e 地址值,左边有两个[
System.out.println(ar2[0]);//[Ljava.lang.String;@5c647e05 地址值,左边有一个[
System.out.println(ar2[0][0]);//null
String[][] ar3 = new String[4][];
System.out.println(ar3);//[[Ljava.lang.String;@33909752 地址值,左边有两个[
System.out.println(ar3[0]);//null
//System.out.println(ar3[0][0]);//报错
double[][] ar4 = new double[4][];
System.out.println(ar4);//[[D@55f96302 地址值,左边有两个[
System.out.println(ar4[0]);//null
//System.out.println(ar4[0][0]);//报错
数组中涉及到的常见算法
-
数组元素的赋值(杨辉三角、回形数等)
//杨辉三角 /* * 1 * 1 1 * 1 2 1 * 1 3 3 1 * 1 4 6 4 1 * 1 5 10 10 5 1 * 1 6 15 20 15 6 1 */ //1.声明并初始化二维数组 int[][] yangHui = new int[10][]; //2.给数组的元素赋值 for (int i = 0; i < yangHui.length; i++) { yangHui[i]= new int[i+1]; //2.1给首末元素赋值 yangHui[i][0] = yangHui[i][i]= 1; //2.2给每行的非首末元素赋值 for (int j = 1; j < yangHui[i].length-1; j++) { yangHui[i][j]= yangHui[i-1][j-1] + yangHui[i-1][j]; } } //3.遍历二维数组 for (int i = 0; i < yangHui.length; i++) { for (int j = 0; j < yangHui[i].length; j++) { System.out.print(yangHui[i][j]+" "); } System.out.println(); } //回形数 /* *1 2 3 4 *12 13 14 5 *11 16 15 6 *10 9 8 7 */ int n = 4; int[][] arr = new int[n][n]; int count = 0; //要显示的数据 int maxX = n-1; //X轴的最大下标 int maxY = n-1; //Y轴的最大下标 int minX = 0; //X轴的最小下标 int minY = 0; //Y轴的最小下标 while(minX <= maxX) { for (int i = minX; i <= maxX; i++) { arr[minY][i] = ++count; } minY++; for (int i = minY; i <= maxY; i++) { arr[i][maxX] = ++count; } maxX--; for (int i = maxX; i >= minX; i--) { arr[maxY][i]= ++count; } maxY--; for (int i = maxY; i >= minY; i--) { arr[i][minX] = ++count; } minX++; } for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length; j++) { String space = (arr[i][j] + " ").length() ==1 ? "0" : ""; System.out.print(space + arr[i][j] + " " ); } System.out.println(); }
-
求数值型数组中元素的最大值、最小值、平均数、总和等
//定义一个int型的一维数组,包含10个元素,分别赋一些随机整数, //然后求出所有元素的最大值,最小值,和值,平均值,并输出出来。 //要求:所有随机数都是两位数。 //初始化数组 int[] arr = new int[10]; for (int i = 0; i < arr.length; i++) { arr[i] = (int)(Math.random() * (99 - 10 + 1) + 10); } //遍历数组 for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]+ " "); } System.out.println(); //求数组的最大值 int maxValue = arr[0]; for (int i = 1; i < arr.length; i++) { if(maxValue < arr[i]) { maxValue = arr[i]; } } System.out.println("最大值: " + maxValue); //求数组元素的最小值 int minValue = arr[0]; for (int i = 1; i < arr.length; i++) { if(minValue > arr[i]) { minValue = arr[i]; } } System.out.println("最小值: " + minValue); //求数组元素的和 int sum = 0; for (int i = 0; i < arr.length; i++) { sum += arr[i]; } System.out.println("和: " + sum); //求数组元素的平均数 double avgValue = (double)sum/arr.length; System.out.println("平均数: " + avgValue);
-
数组的复制、反转、查找(线性查找、二分法查找)
int[] arr1 = new int[] {1,2,3,4,5,6,7,8}; //复制 int[] arr2 = new int[arr1.length]; for (int i = 0; i < arr2.length; i++) { arr2[i]= arr1[i]; } //反转 for(int i = 0,j = arr1.length - 1;i < j;i++,j--) { int temp = arr1[i]; arr1[i] = arr1[j]; arr1[j] = temp; } //查找 //1.线性查找 int dest = 6;//目标值 int flag = false; for (int i = 0; i < arr1.length; i++) { if(arr1[i] == dest) { System.out.println("找到了,下标为:"+i); flag = true; break; } } if(flag){ System.out.println("没找到"); } //2.二分查找:前提是查找的数组必须是有序的 int dest = 6;//目标值 int left = 0;//初始的首索引 int right = arr1.length - 1;//初始的末索引 while(left < right) { int mid = (right + left) / 2; if(dest == arr1[mid]) { System.out.println("找到了,下标为:"+i); }else if(arr1[mid] > dest) { right = mid - 1; }else { left = mid + 1; } }
-
数组元素的排序算法
int[] arr = new int[] {1,5,9,3,8,7,6,4,2}; //冒泡排序 for (int i = 0; i < arr.length - 1; i++) { boolean flag = true; for (int j = 0; j < arr.length - 1 - i; j++) { if(arr[j]> arr[j + 1]) { flag = false; int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } if(flag) { break; } }
Arrays工具类的使用
-
java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。
boolean equals(int[] a,int[] b) 判断两个数组是否相等。 void fill(int[] a,int val) 将指定值填充到数组之中。 void sort(int[] a) 对数组进行排序。 String toString(int[] a) 输出数组信息。 int binarySearch(int[] a,int key) 对排序后的数组进行二分法检索指定的值。 //boolean equals(int[] a,int[] b) int[] arr = new int[] {1,2,3,4}; int[] arr2 = new int[] {1,5,3,8}; boolean isEquals = Arrays.equals(arr, arr2); System.out.println(isEquals);//false //void fill(int[] a,int val) Arrays.fill(arr, 0); //String toString(int[] a) System.out.println(Arrays.toString(arr));//[0, 0, 0, 0] //void sort(int[] a) Arrays.sort(arr2); System.out.println(Arrays.toString(arr2));//[1, 3, 5, 8] //int binarySearch(int[] a,int key) int index = Arrays.binarySearch(arr2, 5); System.out.println(index);//2
数组使用中的常见异常
数组脚标越界异常( ArrayIndexOutOfBoundsException) |
---|
int[] arr = new int[2]; System.out.println(arr[2]); System.out.println(arr[-1]); 访问到了数组中的不存在的脚标时发生。 |
空指针异常(NullPointerException) |
int[] arr = null; System.out.println(arr[0]); arr引用没有指向实体,却在操作实体中的元素时。 |
总结
/*
* 一:数组的概述
* 1.数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
* 2.数组相关的概念
* >数组名
* >元素
* >角标,下标,索引
* >数组的长度,元素的个数
* 3.数组的特点。
* 1)数组是有序排列的
* 2)数组属于引用数据类型的变量。数组的元素既可以是基本数据类型,也可以是引用数据类型
* 3)创建数组对象会在内存中开辟一整块连续的内存空间
* 4)数组的长度一旦确定,就不能改变
* 4.数组的分类
* ①按照维数:一维数组,二维数组。。。
* ②按照数组元素的类型:基本数据类型元素的数组,引用数据类型元素的数组
* 5.一维数组的使用
* ①一维数组的声明和初始化
* ②如何调用数组的指定位置的元素
* ③如何获取数组的长度
* ④如何遍历数组
* ⑤数组元素的默认初始化值
* >数组元素是整型:0
* >数组元素是浮点型:0.0
* >数组元素是char型:0(ASCII码)或'u0000'
* >数组元素是boolean型:false
* >数组元素是引用数据型:null
* ⑥数组的内存解析
* 6.二维数组的使用
* 对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。
* 其实,从数组底层的运行机制来看,其实没有多维数组.
* 二维数组的元素分为外层数组的元素和内层数组的元素
* int[][] arr = new int[4][3];
* 外层数组元素:arr[0],arr[1]等
* 内层数组元素:arr[0][0],arr[1][1]等
* ①一维数组的声明和初始化
* ②如何调用数组的指定位置的元素
* ③如何获取数组的长度
* ④如何遍历数组
* ⑤数组元素的默认初始化值
* 针对与初始化方式一:例如:int[][] arr9 = new int[4][3];
* 外层元素的初始值为:地址值
* 内层元素的初始值为:与一维数组初始情况相同
* 针对于初始化方式二:例如:int[][] arr9 = new int[4][];
* 外层元素的初始值为:null
* 内层元素的初始值为:不能调用,否则报错
* ⑥数组的内存解析
*/