目录
一、数组的更多内容
1.1 Arrays工具类
JDK提供的java.util.Arrays工具类,包含了常用的数组操作,方便我们日常开发。Arrays类包含了:排序、查找、填充、打印内容等常见的操作。
public class TestArray7 {
public static void main(String[] args) {
//定义一个数组
int[] scoreArr = {75, 87, 56, 45, 89, 100, 76, 34, 89, 97};
//遍历数组
System.out.println(Arrays.toString(scoreArr));
//数组排序
Arrays.sort(scoreArr);
System.out.println(Arrays.toString(scoreArr));
//查询数据
int index = Arrays.binarySearch(scoreArr, 89);
System.out.println(index);
//数组的填充
// Arrays.fill(scoreArr,10);
Arrays.fill(scoreArr, 3, 8, 10);
System.out.println(Arrays.toString(scoreArr));
//数组复制
/*
int [] scoreArr2 = new int[10];
for(int i=0;i<scoreArr2.length;i++){
scoreArr2[i] = scoreArr[i];
}*/
int[] scoreArr2 = Arrays.copyOf(scoreArr, scoreArr.length);
//int [] scoreArr2 = Arrays.copyOf(scoreArr,20);
//int [] scoreArr2 = Arrays.copyOf(scoreArr,5);
System.out.println(Arrays.toString(scoreArr2));
//数组比较
boolean flag = Arrays.equals(scoreArr, scoreArr2);
System.out.println(flag);
}
}
注意1:Arrays.binarySearch(arr,elem );是二分查找,要求数组必须有序。
注意2:在JDK8增加parallelSort()方法,为并发排序方法,适合数据量大的情况。
注意3:JDK8后增加了函数式接口、lamda表达式,流式编程有关方法,暂时无法讲解。
1.2 数组的拷贝
Arrays.copyOf()的底层使用了System类的arraycopy( )方法。
public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
public static native void arraycopy(Object src, //源数组
int srcPos, //源数组要复制的起始位置
Object dest,//目的数组
int destPos,//目的数组要复制到的起始位置
int length); //要复制的数组元素的数量
public class TestArray8 {
public static void main(String args[]) {
String[] arr1 = {"阿里", "腾讯", "百度", "京东", "华为"};
System.out.println(Arrays.toString(arr1));
String[] arr2 = new String[10];
System.out.println(Arrays.toString(arr2));
System.arraycopy(arr1, 0, arr2, 0, arr1.length);
//等价于如下语句,但是 System.arraycopy()效率更高
//for (int i = 0; i < arr1.length; i++) { arr2[i] = arr1[i]; }
System.out.println(Arrays.toString(arr2));
Arrays.fill(arr2, null);
System.arraycopy(arr1, 2, arr2, 4, 2);
System.out.println(Arrays.toString(arr2));
}
}
之前的删除和添加操作可以使用System.arrayCopy()优化一下,提供效率。
//删除操作
System.arraycopy(scoreArr,index+1,scoreArr,index,scoreArr.length-1-index);
scoreArr[scoreArr.length-1] = 0;
Arrays.copyOf()和System.arrayCopy()的区别
- Arrays.copyOf()需要一个新的数组,经常用于实现数组扩容。真正复制元素时使用的就是System.arrayCopy();
- System.arrayCopy()是一个native方法(Java本身无法实现,需要调用C/C++代码实现),效率高。可以是两个数组的复制,也可以是一个数组的元素的复制
1.3 可变参数
JDK1.5提供了定义方法时使用可变参数的功能,语法为格式为:参数类型...参数,允许实参可以是0个、1个、n个,甚至数组的形式。可以进步的减少方法重载的数量。
public class Test4 {
public static void main(String[] args) {
int a=10;
int b=20;
int c=30;
int d=40;
int e=50;
int[] arr ={a,b,c,d,e};
methodb("asdf",10.1,a,b,c);
String[] names={};
//methodX(names);
}
/*
* ... 是数组作为方法参数的一种更灵活的替换 可变参数
* 实参是可变 实参可以是一个数组 也可以是多个单独的变量
* 变量的个数0-多个
* 形参仍然当成数组使用
* 1可变参数必须是参数列表中的最后一个参数
* 2在一个方法的参数列表中,只能有一个可变参数
* 3方法重载时,可变参数和数组作为参数认为是相同的数据类型
* */
public static void methodb(String s,double b,int... arr){
for (int i : arr) {
System.out.print(i+"\t");
}
}
/* public static void methodX(String[] arr){
}
public static void methodX(String... arr){
}*/
}
总结1:可变参数关键点
- 可变参数的好处:简单 方便 直观 减少方法重载的数量
- 可变参数只能做方法的形参
- 可变参数的实参可以是0个、1个、多个,也可以是一个数组
- 一旦定义了可变参数,就不能定义数组参数了
- 可变参数底层是一个数组,根据传递参数的个数不同,会创建出不同长度的数组,来存储这些参数传递的参数个数。在方法体中,可变参数就是通过数组来处理的
- 一个方法的可变参数只能有一个,必须是最后一个参数
总结2:可变参数和数组参数的区别和联系
联系
可变参数底层是一个数组,在方法体中可变参数是当做数组来处理的;
方法的实参都可以是数组
区别
1.个数不同
一个方法的可变参数只能有一个;一个方法的数组参数可以有多个
2.位置不同
一个方法的可变参数只能是最后一个;一个方法的数组参数位置任意
3.实参不同
数组参数实参须是数组;可变参数实参可以是0个、1个、多个,一个数组
二、二维数组
2.1 定长二维数组
功能:存储3个班级分别4个学生的分数
思路1:定义一个数组,长度是12,存储12个分数
int [] scoreArr = new int[12];
不合理:一个班级12个学生
思路2:定义3个数组,长度都是4,分别存一个班的分数
int [] scoreArr = new int[4]
int [] scoreArr2 = new int[4]
int [] scoreArr3 = new int[4]
不合理:数组太多了
思路3:目标:数组少,能够区分3个班级
定义一个二维数组,一个数组就可以存储3个班分别四个学生的信息
public class Test2 {
public static void main(String[] args) {
// 规定最外层大数组的长度即可 内部的每一个小数组长度是可以不一致的
int[][]arr = {{10,20,30,40},{66,88},{100,200,300}};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j <arr[i].length; j++) {
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
}
}
2.2 不定长二维数组
功能:存储3个班级,每个班最多4个学生的分数
public class Test2 {
public static void main(String[] args) {
// 规定最外层大数组的长度即可 内部的每一个小数组长度是可以不一致的
int[][] arr=new int[5][];
arr[0]=new int[]{1,2,3,4};
arr[1]=new int[]{2,3,4,5,6,7,8,9};
arr[2]=new int[]{11,22};
arr[3]=new int[]{33,44,55,66};
arr[4]=new int[]{9,8,7,6,5,4};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j <arr[i].length; j++) {
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
}
}
2.3 二维数组的遍历
2.3.1 普通循环
public static void main(String[] args) {
int[][]arr = {{10,20,30,40},{66,88},{100,200,300}};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
}
2.3.2 增强for循环
public static void main(String[] args) {
int[][]arr = {{10,20,30,40},{66,88},{100,200,300}};
for (int[] arrays : arr) {//arrays 二维数组内的每一个数组
for (int ele : arrays) {
System.out.print(ele+"\t");
}
System.out.println();
}
}
2.3.3 Arrays工具类遍历
int[][]arr = {{10,20,30,40},{66,88},{100,200,300}};
System.out.println(Arrays.deepToString(arr));
总结1:有一维数组,有二维数组,就有三维数组,四维数组.....
- 一维数组:存储一个班10个学生的分数
- 二维数组:存储5个班各10个学生的分数
- 三维数组:存储6个年级个5个班各10个学生的分数
- 四维数组:存储10个学校6个年级个5个班各10个学生的分数
总结2:其实只要一维数组,没有二维数组,三维数组
- int [] scoreArr = new int[10] 定义一个一维数组,长度是10,元素是int类型
- int [][] scoreArr = new int[5][10] 定义一个一维数组,长度是5,每个元素是一个一维数组
- int [][][] scoreArr = new int[3][5][10] 定义一个一维数组,长度是3,每个元素是一个二维数组
总结3:二维数组的静态初始化
- int [] [] scoreArr = new int[][]{{90,100,90,100},{89,89,0},{100,0}};
- int [] [] scoreArr = {{90,100,90,100},{89,89,0},{100,0}};
总结4:实际开发中多维数组用的非常少