上次我们简单的把 Java数组 中:数组的声明、以及赋值方式、给数组分配空间、以及数组的两种初始化方式, 说啦一下这次我会把我接触到的数组知识全部写全,以供大家参看。
开始正经扯题:
老样子学习之前推荐相关学习资料:【仅供大家参考】
数组学习教程推荐:
- 1.北京高淇Java300集(Java强烈推荐)
Java300集零基础适合初学者视频教程_Java300集零基础教程_Java初学入门视频基础巩固教程_Java语言入门到精通 - 2.JavaSE基础全套-从零开始进阶之大神(数组推荐)
JavaSE知识基础全套-从0开始进阶大神_JavaSE基础知识体系从入门到精通框架_/JAVA基础/数组/OOP/集合/IO流 - 3.Java全套课程-基础必备课程
JAVA全套课程_Java入门_Java零基础必备_Java编程课程_Java核心基础_EasyUI_SSM整合框架_Redis_高并发—全套课程 - 4.Java常用类基础实战
日常推荐Java常用类基础实战_通俗易懂实战入门教程_Java八大常用类核心基础/Java包装类/String类 - 5.Java基础入门必备数学知识【数据结构与算法】(数组推荐)
Java基础入门必学知识数据结构与算法_Java数据结构与算法基础到进阶_Java面试常见数据结构和算法问题_排序算法_递归_折半查询_栈和队列_链表 - 6.Java面向对象编程_OOP基础深入讲解
Java面向对象编程重基础深入讲解_OOP面向对象Java基础干货分享/JavaSE/面向对象编程/OOP程序设计 - 7.GOF23种设计模式-23中设计模式详解课程
GOF23种设计模式讲解_Java gof23种设计模式详解课程_从单例到备忘录模式 23种模式详解
一、数组应用【增删查】:
1、查询数组元素
查询数组可以查询指定索引的元素的内容,直接按照索引定位即可;
可以按照指定内容元素的索引,需要逐个比较,直到找到为止,或者比较到数组的末尾也没有找到。
代码实现:
public class TestArray3{
public static void main(String [] args){
//使用数组存储10个学生的分数
int [] scoreArr = {75,87,56,45,89,100,76,34,89,97};
//获取第8个学生的分数 1 8
int position = 2;
int score = scoreArr[position-1];
System.out.println("第"+position+"个学生的分数是:"+score);
//获取分数的76的学生的索引(第一个)
int index = -1;
int elem = 101;
for(int i=0;i<scoreArr.length;i++){
if(elem == scoreArr[i]){
index = i;
break;
}
}
if(index == -1){
System.out.println("数组中不存在该值:"+elem);
}else{
System.out.println(elem+"在数组中的索引:"+index);
}
}
}
结论1:
数组按照索引查询数据,效率最高;不管索引是哪个,花费的时间是一样的;
原理: 分配连续的空间,且每个元素的空间大小是相同的,所以指定索引的元素位置=数组的起始位置+每个元素的大小*索引,无需进行逐个比较。
结论2:
数组按照内容查询数据效率低下;
一般需要从第一个元素逐次比较,直到找到位置;或者比较到数组的最后一个元素也没有找到,则确认无该元素。
如果数组的数据是大小有序的,可以通过折半查找的方式来提高查询效率。
2、删除元素
如何删除指定索引的元素;
public class TestArray4{
public static void main(String [] args){
//1.使用数组存储分数
int [] scoreArr = {75,87,56,45,89,100,76,34,89,97};
//2.删除之前输出
System.out.println("删除前");
for(int score :scoreArr){
System.out.print(score+"\t");
}
//3.删除索引为4的元素
int index = 4;
//3.1从第i个元素开始,将后一个元素前移一个位置
for(int i = index; i<scoreArr.length-1;i++){
scoreArr[i]=scoreArr[i+1];
}
//3.2最后一个元素置为0
scoreArr[scoreArr.length-1] = 0;
//4.删除之后输出
System.out.println("\n删除后");
for(int score :scoreArr){
System.out.print(score+"\t");
}
}
}
结论1:数组的优点:
-
一个数组可以存储多个元素
-
按照索引查询元素效率高
结论2:数组的缺点:
-
按照内容查询元素,效率低下
-
进行删除和添加时候需要大量的移动元素,效率低下;
-
长度固定
可以提取删除数组元素的方法,直接调用该方法即可实现删除。注意:这可是第一次使用数组做方法的形参。
public class TestArray5{
public static void main(String [] args){
//使用数组存储分数
int [] scoreArr = {75,87,56,45,89,100,76,34,89,97};
//删除之前输出
System.out.println("删除前");
for(int score :scoreArr){
System.out.print(score+"\t");
}
//3.删除索引为4的元素
int index = 4;
deleteElem(scoreArr,index);
//删除之后输出
System.out.println("\n删除后");
for(int score :scoreArr){
System.out.print(score+"\t");
}
}
public static void deleteElem(int [] arr,int index){
//3.1从第index个元素开始,将后一个元素前移一个位置
for(int i = index; i<arr.length-1;i++){
arr[i]=arr[i+1];
}
//3.2最后一个元素置为0
arr[arr.length-1] = 0;
}
}
使用数组作为方法的形参,这还是第一次。内存分配图如图所示:
3、添加数组元素
需要实现:在数组的索引为i的位置添加一个新的值value。
实现思路和删除类似,需要大量的移动元素。需要从末尾开始,将后面元素都后移一个位置,空出第i个位置来,再放入要添加的元素值value。
代码实现:
public class TestArray6 {
public static void main(String [] args){
//使用数组存储分数
int [] scoreArr = {75,87,56,45,89,100,76,34,0,0};
//添加之前输出
System.out.println("添加前");
for(int score :scoreArr){
System.out.print(score+"\t");
}
//3.在索引为4的位置添加90
int index = 4;
int value = 90;
insertElem(scoreArr,index,value);
//添加之后输出
System.out.println("\n添加后");
for(int score :scoreArr){
System.out.print(score+"\t");
}
}
public static void insertElem(int [] arr,int index,int value){
//从最后一个元素开始,将前一个元素后移一个位置
for(int i = arr.length-1; i>index;i--){
arr[i]=arr[i-1];
}
//第index的元素赋值为value
arr[index] = value;
}
}
二、数组的更多的内容
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表达式,流式编程有关方法,暂时无法讲解。
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++代码实现),效率高。 可以是两个数组的复制,也可以是一个数组的元素的复制
3、可变参数
JDK1.5 提供了定义方法时使用可变参数的功能,语法为格式为:参数类型...参数,允许实参可以是0个、1个、n个,甚至数组的形式。可以进步的减少方法重载的数量。
代码实现:
public class TestArray9{
public static void main(String [] args){
System.out.println(add());
System.out.println(add(10));
System.out.println(add(10,20));
System.out.println(add(10,20,30));
System.out.println(add(10,20,30,40,50));
int [] numArr ={10,20,30,40,50};
System.out.println(add(numArr));
}
public static int add(int ... numArr){
int sum = 0;
for(int num :numArr){
sum += num;
}
return sum;
}
}
总结1:可变参数关键点
- 可变参数的好处:简单 方便 直观 减少方法重载的数量
- 可变参数只能做方法的形参
- 可变参数的实参可以是0个、1个、多个,也可以是一个数组
- 一旦定义了可变参数,就不能定义数组参数了
- 可变参数底层是一个数组,根据传递参数的个数不同,会创建出不同长度的数组,来存储这些参数传递的参数个数。在方法体中,可变参数就是通过数组来处理的
- 一个方法的可变参数只能有一个,必须是最后一个参数
总结2:可变参数和数组参数的区别和联系
联系
- 可变参数底层是一个数组,在方法体中可变参数是当做数组来处理的;
- 方法的实参都可以是数组
区别
1.个数不同: 一个方法的可变参数只能有一个;一个方法的数组参数可以有多个
2.位置不同: 一个方法的可变参数只能是最后一个;一个方法的数组参数位置任意
3.实参不同: 数组参数实参须是数组;可变参数实参可以是0个、1个、多个,一个数组
\
三、二维数组
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 TestArray10 {
public static void main(String[] args) {
//定义一个二维数组
int[][] scoreArr = new int[3][4];//
//存储3个班级分别4个学生的分数
scoreArr[0][0] = 90;
scoreArr[0][1] = 100;
scoreArr[0][2] = 90;
scoreArr[0][3] = 100;
scoreArr[1][0] = 89;
scoreArr[1][1] = 89;
scoreArr[2][2] = 100;
//输出分数
System.out.println(scoreArr.length);
System.out.println(scoreArr[0].length);
System.out.println(scoreArr[0][0]);//90
System.out.println(scoreArr[1][0]);//89
System.out.println(scoreArr[2][0]);//0
System.out.println(scoreArr[2][1]);//100
//遍历数组的所有元素
for (int i = 0; i < scoreArr.length; i++) {
System.out.println("第" + (i + 1) + "个班的学生分数");
for (int j = 0; j < scoreArr[i].length; j++) {
System.out.print(scoreArr[i][j] + "\t");
}
System.out.println();
}
}
}
图解:
2、不定长二维数组
举例功能:存储3个班级,每个班最多4个学生的分数.
实现代码:
public class TestArray11{
public static void main(String [] args){
//定义一个二维数组
int [][] scoreArr = new int[3][];
scoreArr[0] = new int[4];
scoreArr[1] = new int[3];
scoreArr[2] = new int[2];
//存储3个班级分别4个学生的分数
scoreArr[0][0] = 90;
scoreArr[0][1] = 100;
scoreArr[0][2] = 90;
scoreArr[0][3] = 100;
scoreArr[1][0] = 89;
scoreArr[1][1] = 89;
scoreArr[2][1] = 100;
//输出分数
System.out.println(scoreArr.length);//3
System.out.println(scoreArr[0].length);//4
System.out.println(scoreArr[1].length);//3
System.out.println(scoreArr[2].length);//2
//遍历数组的所有元素
for(int i=0;i<scoreArr.length;i++){
System.out.println("第"+(i+1)+"个班的学生分数");
for(int j=0;j<scoreArr[i].length;j++){
System.out.print(scoreArr[i][j]+"\t");
}
System.out.println();
}
}
}
图解:
二维数组总结:
总结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:实际开发中多维数组用的非常少,一般最多使用二维数组.
以上就是 Java入门【数组篇】 全部内容,喜欢的同学记得点个赞支持一下哦~
上方知识点全部动手操作一篇你会收获很多的~~如需要资料推荐的哪些课程资料,可以订阅主页的公众号.
感谢阅读~