9、Java数组
9.1 定义
-
数组是一种引用类型,可以存放多个同一类型的数据。
-
数组初始化:
-
动态初始化:数据类型[] 数组名 = new 数据类型[数组大小] 如:int[] a = new int[5]//创建一个名为a的数组,存放5个int类型的数据
-
动态初始化:先声明数组 : 数据类型[] 数组名 再创建数组 : 数组名=new 数据类型[数组大小] 如:double[] b;b=new double[10]
声明时没有分配内存地址,这时b的值为null,用new创建后分配了内存空间,可以存放数据
-
静态初始化:数据类型[] 数组名 = {元素值,…}; 如 int[] c ={1,5,8,3,4,10}
-
还可以这样初始化: String[] arr = new String[]{“a”,“b”,“c”}
9.2 使用细节
-
-
数组索引从0开始
-
数组中元素可以存放任何数据类型,包括基本数据类型和引用类型,但是不能混用
-
数组创建后,若没有赋值,会分配默认值,int->0; short->0; byte->0; long->0; float->0.0; double->0.0; char->\u0000; boolean->false; String->null
-
数组属于引用类型,数组型数据是对象(object)
9.3 数组赋值机制
基本数据类型赋值是具体的数据,互相不影响。如int n1 = 2;int n2 = n1; n2 =80;若现在改变n2的值,不影响n1的值
但是数组默认情况下是引用传递,赋的值是地址
//数组是引用传递,赋的值是地址
int[] arr1 = {1,4,3};
int[] arr2 = arr1;
arr2[0] = 0;
arr1[1] = 10;
System.out.println("arr2数组值为:");
for(int i = 0;i<arr2.length;i++){
System.out.print(arr2[i]+" ");
}
System.out.println();
System.out.println("arr1数组值为:");
for(int i = 0;i<arr1.length;i++){
System.out.print(arr1[i]+" ");
}
/*
arr2数组值为:
0 10 3
arr1数组值为:
0 10 3
*/
int[] arr1 = {1,2,3};
int[] arr2 = {4,5,6};
arr1 = arr2;
//这里arr1地址指向arr2地址,原来给arr1分配的地址被JVM销毁
9.4 数组拷贝
不同于上一节数组赋值机制,数组拷贝是内容复制,并不改变原来数组的内容,要求数据空间独立
int[] arr1 = {1,4,3};
//创建一个新的数组arr2,开辟新的数据空间,并且大小为arr1.length
int[] arr2 = new int[arr1.length];
//遍历arr1将每个元素拷贝到arr2对应的位置
for(int i = 0;i<arr1.length;i++){
arr2[i] = arr1[i];
}
arr2[0] = 0;
arr1[1] = 10;
System.out.println("arr2数组值为:");
for(int i = 0;i<arr2.length;i++){
System.out.print(arr2[i]+" ");
}
System.out.println();
System.out.println("arr1数组值为:");
for(int i = 0;i<arr1.length;i++){
System.out.print(arr1[i]+" ");
}
System.out.println();
/*
arr2数组值为:
0 4 3
arr1数组值为:
1 10 3
*/
9.5 数组反转
如将arr={11,22,33,44,55,66}反转为{66,55,44,33,22,11}
int[] arr = {11,22,33,44,55,66,77};
int temp = 0;
for(int i = 0;i<arr.length/2;i++){//奇数偶数都是arr.length/2
temp = arr[i];
arr[i] = arr[arr.length-i-1];
arr[arr.length-i-1] = temp;
}
for(int i = 0;i< arr.length;i++){
System.out.print(arr[i]+" ");
}
9.6 数组扩容
如将arr={1,2,3}扩展为arr={1,2,3,4}
int[] arr = {1,2,3};
int[] arrTemp = new int[arr.length+1];
for(int i = 0;i<arr.length;i++){
arrTemp[i] = arr[i];
}
arrTemp[arrTemp.length-1] = 4;
arr = arrTemp;//原来指向的地址被JVM销毁
System.out.println("扩容后的arr为:");
for(int i = 0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
9.7 排序
这里介绍简单的冒泡排序算法,更多排序算法将在后续算法中详细讲述
排序的分类:
- 内部排序:将需要处理的所有数据加载到内部存储器中进行排序。包括(交换式排序法;选择式排序法和插入式排序法)
- 外部排序:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)
- 冒泡排序:一个长为length的无序数组,用冒泡排序需要排length-1轮,首轮需要比较length-1次,之后每轮比较次数递减1
int[] arr = {24,69,80,57,13,1,66,34,9,0,57};
int temp = 0;
for(int i = 0;i<arr.length-1;i++){
System.out.println("第"+ (i+1) +"轮比较:");
for(int j = 0;j<arr.length-i-1;j++){
System.out.println("第"+ (i+1) +"轮第"+ (j+1) + "次比较");
if(arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第"+(i+1)+"轮比较结果:");
for(int k = 0;k<arr.length;k++){
System.out.print(arr[k]+" ");
}
System.out.println();
}
冒泡优化:在每轮比较前设置一个flag=0,每次发生比较行为则flag++;在每轮比较完成后判断flag是否为0;若为0,则说明此时数组有序;不需要之后的所有轮次比较,提前break返回有序数组即可
9.8 查找
java常用的的两种查找有顺序查找和二分查找
String[] names = {"张三","李四","王五","赵六"};
System.out.println("请输入查找的名称:");
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
int flag = 0;
for(int i = 0;i<names.length;i++){
if(name.equals(names[i])){
System.out.println("找到了,在第" + (i+1) + "的位置");
flag=1;
break;
}
}
if(flag==0){
System.out.println("查无此人!");
}
9.9 二维数组
-
动态初始化:
数据类型[][] 数组名 = new 数据类型[大小1][大小2]
第一个大小表示有多少个一维数组,第二个大小表示每一个一维数组里有多少个元素;比如 :
int[][] arr = new int[2][3];
-
也可以先声明,再创建 :
数据类型[][] 数组名;
数组名 = new 数据类型[大小1][大小2]
-
列数不确定:即大小2不是统一的长度,可以动态创建二维数组。
int[][] arr = new int[3][];//创建二维数组,一共有3个一维数组,但是每一个一维数组没有开辟数据空间 for(int i = 0;i< arr.length;i++){ arr[i] = new int[i+1];//给每一个一维数组开辟数据空间 for(int j = 0;j<arr[i].length;j++){ arr[i][j] = i+1;//赋值 } } for(int i = 0;i<arr.length;i++){ for(int j = 0;j<arr[i].length;j++){ System.out.print(arr[i][j]+" "); } System.out.println(); }
-
静态初始化:
数据类型[][] 数组名 = {{值,值,值},{值,值},{值}}
练习:打印杨辉三角
System.out.println("输入杨辉三角的行数:");
Scanner scanner = new Scanner(System.in);
int row = scanner.nextInt();
int[][] arr = new int[row][];
for(int i = 0;i<arr.length;i++){
arr[i] = new int[i+1];
for(int j = 0;j<arr[i].length;j++){
if(j==0||j==arr[i].length-1){
arr[i][j]=1;
}
else{
arr[i][j] = arr[i-1][j-1]+arr[i-1][j];
}
}
}
for(int i = 0;i<arr.length;i++){
for(int j = 0;j<arr[i].length;j++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
-
注意:二维数组还可以这样声明
int[] arr[] = new int[][]
int[] x,y[];
中,x表示一维数组,y表示二维数组