Java入门姿势【数组篇2】

2021/8/7 12:06:00

本文主要是介绍Java入门姿势【数组篇2】,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

上次我们简单的把 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:数组的优点:

1) 一个数组可以存储多个元素

2) 按照索引查询元素效率高

结论2:数组的缺点:

1) 按照内容查询元素,效率低下

2) 进行删除和添加时候需要大量的移动元素,效率低下;

3) 长度固定

可以提取删除数组元素的方法,直接调用该方法即可实现删除。注意:这可是第一次使用数组做方法的形参。

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入门【数组篇】 全部内容,喜欢的同学记得点个赞支持一下哦~

上方知识点全部动手操作一篇你会收获很多的~~如需要资料推荐的哪些课程资料,可以订阅主页的公众号

感谢阅读~



这篇关于Java入门姿势【数组篇2】的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程