美文网首页
JavaSE进阶三 数组

JavaSE进阶三 数组

作者: SimonLike | 来源:发表于2021-06-09 10:09 被阅读0次

数组的定义

  • 1,java语言中的数组是一种引用数据类型,不属于基本数据类型。数组的父类是Object。

  • 2,数组是一个容器,可以同时容纳多个元素。(数组是一个数据的集合)

  • 3,数组当中可以存储基本数据类型的数据,也可以存储引用数据类型的数据。

  • 4,数组是引用类型,所以数组对象是存在堆内存中的。

  • 5,数组当中如果存储的是"java对象"的话,实际上存储的是对象的"引用(内存地址)",数组中不能直接存储java对象。

  • 6,数组一旦创建,在Java语言中规定,长度不可变。(数组长度不可变)

  • 7,数组分类:一维数组,二维数组,三维数组,多维数组...(一维数组使用较多,二维偶尔使用)

  • 8,所有数组对象都有length属性(java自带的),用来获取数组中元素的个数。

  • 9,java中的数组要求数组中元素类型统一;比如int类型数组只存储int类型,Person类型数组只存储Person类型。

  • 10,数组在内存方面存储的时候,数组中的元素内存地址(存储的每个元素都是有规则的挨着排列的)是连续的,内存地址连续。 这是数组存储元素的特色,数组实际上是一种简单的数据结构。

  • 11,数组中首元素的内存地址作为整个数组对象的内存地址。

  • 12,数组中每个元素都有下标,下标从0开始,以1递增;最后一个元素的下标是:length - 1。 下标非常重要,我们对数组中元素进行"存取"的时候,都需要通过下标来进行。

  • 13,数组的优点和缺点?

    优点:
        查询/查找/检索某个下标元素时效率极高,可以说是查询效率最高的一个数据结构。
        为什么检索效率高?
            1,每个元素的内存地址在空间存储上是连续的。
            2,每个元素类型相同,所占用空间大小一样。
            3,知道第一个元素内存地址,知道每个元素占用空间的大小,知道下标,所有通过一个
            数学表达式就可以计算出某个下标元素的内存地址,直接通过内存地址定位元素,所以数组的
            检索效率是最高的。
    
            数组中存储100个元素,或者存储100万个元素,在元素查询/检索方面,效率是相同的,因为数组中元素查找的时候
            不会一个一个的找,是通过数学表达式计算出来的。(酸菜一个内存地址,直接定位的)
    缺点:
        1,由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或增加元素的时候,
    效率较低,因为随机增删元素会涉及后面元素统一向前或向后移位的操作。
        2,数组不能存储大数据量,因为很难在内存空间上找到一块特别大的连续空间。
    
    注意:对于数组中最后一个元素的增删是没有效率影响的。
    
  • 14,声明/定义一个一维数组

    int[] array1;
    double[] array2;
    String[] array3;
    ...
    
  • 15,初始化一个一维数组?

    • 两种方式:静态初始化一维数组,动态初始化一维数组。

    静态初始化语法格式:

      int[] array = {1,2,3,4,5}
    

    动态初始化语法格式:

      int[] array = new int[5]; // 5表示数组的元素个数。
                               // 初始化一个5个长度int类型数组,每个元素默认值0.
      String[] names = new String[6] // 初始化一个6个长度String类型数组,每个元素默认值null
    
  • 16,什么时候采用静态初始化方式,什么时候采用动态初始化方式?

      当你创建数组的时候,确定数组中存储哪些具体元素时,采用静态初始化方式。
    
     当你创建数组的时候,不确定将来数组中存储哪些数据,你可以采用动态初始化的方式,预先分配内存空间。
    
代码示例
public class Array01 {
    public static void main(String[] args) {
        //使用静态初始化方式声明一个int类型数组
        int[] arr1 = {1,3,4,6,62};
        // 数组中的length属性
        System.out.println("数组中元素的个数:" + arr1.length);

        // 使用下标对数组中的元素进行存取
        // 取(读)
        System.out.println("数组中第一个元素:" + arr1[0]);
        System.out.println("数组中最后一个元素:" + arr1[arr1.length - 1]);

        // 存(修改)
        // 把第一个元素修改为11
        arr1[0] = 11;
        // 把最后一个元素修改为119
        arr1[arr1.length - 1] = 119;

        System.out.println("数组中第一个元素:" + arr1[0]);
        System.out.println("数组中最后一个元素:" + arr1[arr1.length - 1]);

       //遍历数组
        for (int i = 0 ;i < arr1.length; i++ ){
            System.out.println(arr1[i]);
        }
        // 下标为5表示第6个元素,数组中没有第6个元素,越界了;会出现异常
        // System.out.println(arr1[6]);//ArrayIndexOutOfBoundsException(数组越界异常)

        // 倒序遍历数组
        for (int i = arr1.length - 1 ; i >=0 ; i-- ){
            System.out.println("倒序-->" + arr1[i]);
        }
       
        // -------------------------------------------------------------------------------
       
        // 初始化动态数组
        int[] arr = new int[4];
        for (int i = 0;i < arr.length; i++){
            System.out.println("数组中下标" + i + "的元素是:" + arr[i]);
        }

        //初始化一个Object类型的数组,采用动态方式初始化
        Object[] objs = new Object[3]; // 3个长度,动态初始化,每个元素默认值是null
        for (int i = 0 ; i < objs.length; i++){
            System.out.println(objs[i]);
        }
        
        
    }
}

数组存储 "引用数据类型"

  • 一维数组的深入,数组中存储的类型为:引用数据类型
  • 对于数组来说,只能存储java对象的"内存地址"。数组中存储的每个元素是"引用"。
代码示例
public class Array02 {
    public static void main(String[] args) {
        // 创建一个Animal类型的数组
        Animal a1 = new Animal();
        Animal a2 = new Animal();
        Animal[] animals = {a1,a2};
        // 对Animal数组进行遍历
        for (int i = 0; i < animals.length; i++){

            // Animal a = animals[i];
            // a.move();
            // 代码合并
            animals[i].move();
        }

        //------------------------------------------------

        // 动态初始化一个长度为2的Animal类型的数组
        Animal[] animals2 = new Animal[2];
        animals2[0] = new Animal();
        // Animal数组中可以存储Cat类型数据,因为Cat是一个Animal。
        // Cat 是Animal的子类。
        animals2[1] = new Cat();

        //------------------------------------------------

        // 创建一个Animal类似的数组,数组中存储Cat和Bird
        Animal[] animals3 = {new Cat(),new Bird()};
        // 对Animal数组进行遍历
        for (int i = 0; i < animals3.length; i++){

            // 调用的方法是父类型中存在的方法不需要向下转型,直接使用父类引用调用即可。
            animals3[i].move();

            // 调用子类特有方法,父类中没有的方法  需要向下转型(多态)
            if (animals3[i] instanceof Cat){
                ((Cat) animals3[i]).moveCat();
            }else if (animals3[i] instanceof Bird){
                ((Bird) animals3[i]).moveBird();
            }

        }
    }
}
class Animal{
    public void move(){
        System.out.println("Animal move--");
    }
}

class Cat extends Animal{
    public void move(){
        System.out.println("Cat move--");
    }

    public void moveCat(){
        System.out.println("猫在抓老鼠--");
    }
}

class Bird extends Animal{
    public void move(){
        System.out.println("Bird move--");
    }
    public void moveBird(){
        System.out.println("鸟儿在飞翔--");
    }
}

数组的扩容

  • 在java开发中,数组长度一旦确定不可变,那么数组满了怎么办?

    • 数组满了,需要扩容。
    • 先新建一个大容量的数组,然后将小容量数组中的数据一个一个的拷贝到大数组中。
  • 数组扩容效率较低,因为涉及拷贝问题。所以在以后的开发中注意:尽可能少的进行数组的拷贝。

  • 可以在创建数组对象的时候预估一下多长合适,最好预估准确,这样可以减少数组的扩容次数,提高效率。

代码示例
public class Array03 {
    public static void main(String[] args) {
        // java中的数组是如何进行拷贝的
        // 拷贝源 (从这个数组中拷贝)
        int[] arr = {1,3,5,7,6};
        // 拷贝目标(拷贝到这个目标数组上)
        int[] dest = new int[10];// 每个默认元素为0

        // 调用JDK System类中的arraycopy方法,来完成数组的拷贝。
        // 将arr数组中的数据从下标1开始,拷贝2个元素
        // 放入dest数组中,从下标3开始。
        System.arraycopy(arr,1,dest,3,2);

        // 将arr数组中的数据全部拷贝到dest数组中,dest数组从下标0开始。
        // System.arraycopy(arr,0,dest,0,arr.length);

        for (int i = 0;i< dest.length; i++){
            System.out.println("dest-->" + dest[i]);
        }

    }
}

二维数组

  • 二维数组其实是一个特殊的一维数组,特殊在这个一维数组当中的每一个元素是一个一维数组。

  • 三维数组是一个特殊的二维数组,特殊在这个二维数组中的每一个元素是一个一维数组。实际开发中
    使用最多的是一维数组,二维数组也很少使用,三维数组几乎不用。

  • 二维数组的静态初始化

  • int[][] array = {{1,2,3},{4,5,9,6},{5,6,7},...};
    
代码示例
public class Array04 {
    public static void main(String[] args) {
        // 一维数组
        int[] array = {1,3,2,5,9};
        int[] array1 = {32,23,54,95};
        int[] array2 = {15,36,22,53,92,23,55};

        // 二维数组
        // 里面是3个一维数组
        int[][]arr = {array,array1,array2};

        System.out.println("二维数组长度:" + arr.length);// 3

        for (int i = 0;i<arr.length;i++){
            System.out.println(arr[i].length);// 输出arr中元素(一维数组)的长度: 5 4 7
        }

        System.out.println("--------------------------------------------------");

        // 取二维数组中第1个元素(一维数组)中的第1个元素
        System.out.println(arr[0][0]);
        // 取二维数组中第2个元素(一维数组)中的第3个元素
        System.out.println(arr[1][2]);
        // 取二维数组中第3个元素(一维数组)中的第4个元素
        System.out.println(arr[2][3]);

        // 修改二维数组中第1个元素(一维数组)中的第1个元素
        arr[0][0] = 320;
        System.out.println(arr[0][0]);

        System.out.println("--------------------------------------------------");

        // 遍历二维数组
        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("这是第" + (i + 1) + "个一维数组");
        }

        System.out.println("--------------------------------------------------");

        // 动态初始化二维数组
        // 3个一维数组,每个一维数组有4个元素

        int[][] a34 = new int[3][4];

        for (int a = 0;a<a34.length;a++){
            
            for (int j = 0; j < a34[a].length; j++){
                System.out.print( a34[a][j] + " " );
            }
            System.out.println("这是第" + (a + 1) + "个一维数组");
        }
    }
}

数组--冒泡排序算法

  • 每次循环结束之后,都要找出最大的数据,放到参与比较的这堆数据的最右边。(冒出最大的那个气泡。)
  • 核心:拿走左边的数字和右边的数字比对,当左边 > 右边,交换位置。
代码示例
public class Sort01 {
    public static void main(String[] args) {
        int[] arr = {2,8,6,3,1,9,4};
        int count = 0;
        // 使用冒泡排序算法进行排序
        for (int i = arr.length-1 ; i > 0; i--) {
            System.out.println("i-->" + i);

            for (int j = 0; j < i ; j++) {
                System.out.println("j=" + j + ";" + "arr[j]=" + arr[j] + ";" + "arr[j+1]=" + arr[j+1]);

                if (arr[j] > arr[j+1]){
                    count++;
                    int temp ;
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }

        System.out.println("交换位置次数:"+ count);

        // 排序之后遍历输出
        for (int a = 0;a < arr.length;a++){
            System.out.println(arr[a]);// 从小到大
        }
    }
}

数组--选择排序

  • 每一次从这堆参与比较的数据当中找出最小值,拿着这个最小值和最前面的元素交换位置。

  • 选择排序比冒泡排序好在: 每一次交换位置都是有意义的。

代码示例
public class Sort02 {
    public static void main(String[] args) {
        int[] arr = {2,8,6,3,1,9,4};

        int count = 0;

        // 使用选择排序算法进行排序(7条数据循环6次)
        for (int i = 0 ; i < arr.length - 1; i++) {
            int min = i;
            for (int j = i+1; j < arr.length; j++){
                if (arr[min] > arr[j]){
                    min = j;// 最小值元素的下标
                }
            }
            int temp ;
            // 当i和min相等时,不交换位置,
            // 当i和min不相等是,表示有更小的元素,需要拿更小的元素和最左边的元素交换位置。
            if (min != i){
                count++;
                // arr[min] 最小的元素
                // arr[i] 最前面的元素
                temp = arr[min];
                arr[min] = arr[i];
                arr[i] = temp;
            }
        }
        // 相对于冒泡排序 交换位置次数变少了
        System.out.println("交换位置次数:"+ count);

        // 排序之后遍历输出
        for (int a = 0;a < arr.length;a++){
            System.out.println(arr[a]);// 从小到大
        }
    }
}

数组--元素的查找

  • 数组元素查找有两种方式:
    • 1,一个一个挨着找,直到找到为止。
    • 2,二分法查找(算法),这个效率较高。
      二分法查找是基于排序的基础之上的。(没有排序的数据是无法查找的)
代码示例
public class Search {
    public static void main(String[] args) {
        int[] arr ={2,34,55,66,22,42,68,88};
        // 需求找到22的下标,如果没找到返回-1

        // 一个一个挨着找
        int index = ArrSearch(arr,68);
        System.out.println(index== -1 ? "该元素不存在!":"该元素的下标是:"+index);

        // --------------------------------------------------------------------

        //  二分法查找
        Arrays.sort(arr);// 对数组进行排序
        int index2 = ArrUtilSearch(arr,42);

        // 以下写法是sun公司封装好的二分法查询
        //int index2 = Arrays.binarySearch(arr,42);

        System.out.println(index2== -1 ? "该元素不存在!":"该元素的下标是:"+index2);
    }

    /**
     * 从数组中查找目标元素的下标(二分法查找)
     * @param array  被检索的数组(必须是已经排序的)
     * @param i 目标元素
     * @return -1表示该元素不存在,大于等于0的数表示元素的下标
     */
    private static int ArrUtilSearch(int[] array, int i) {

        int begin = 0;// 开始下标
        int end = array.length -1; // 最后一个元素的下标

       while (begin <= end){
           int mid = (begin + end) / 2; // 中间元素下标

           if (array[mid] == i){
                return mid;
            }else if (array[mid] < i){
                // 目标元素在中间元素的右边
                // 开始元素的下标重新赋值
                begin = mid + 1;
            }else {
                // 目标元素在中间元素的左边
                // 最后一个元素的下标需要重新赋值
                end = mid - 1;
            }
       }

        // 程序执行到此处,表示没有找到元素
        return -1;
    }

    /**
     * 从数组中检索某个元素的下标(一个一个的查找)
     * @param array 被检索的数组
     * @param a 被检索的元素
     * @return -1表示该元素不存在,大于等于0的数表示元素的下标
     */
    public static int ArrSearch(int[] array,int a){
        for (int i = 0;i<array.length;i++){
            if (array[i] == a){
                return i;
            }
        }
         // 程序执行到此处,表示没有找到元素
        return -1;
    }
}

上篇:JavaSE进阶二 Object中的方法
下篇:JavaSE进阶四 String

相关文章

  • JavaSE进阶三 数组

    数组的定义 1,java语言中的数组是一种引用数据类型,不属于基本数据类型。数组的父类是Object。 2,数组是...

  • JavaSE进阶-02-数组

    数组(Array)特性:1.Java语言中的数组是一种引用数据类型,不属于基本数据类型。数组的父类事Object。...

  • JavaSE——数组集合

    声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互...

  • JavaSE之数组

    一维数组:一条线 二维数组:一个面 三维数组:一个立方体,三维数组使用较少,这里不提及。 一维数组 数组的创建 声...

  • JavaSE 数组排序

    Java数组排序是数组操作常用操作之一,通过排序将数组中原来顺序按照升序(从小到大)或降序(从大到小)重新组织。数...

  • javaSE - 006 - 数组

    定义,java的数组是引用类型 相同数据类型的连续的数据空间1.动态初始化 2.静态初始化

  • JavaSE之数组

    六、数组 目录:数组概述、数组声明创建、数组使用、多维数组、Array类、稀疏数组 1.什么是数组 数组的定义:数...

  • JavaSE之数组

    课前小例 数据类型: 1.基本数据类型:byte short int long float double char...

  • JavaSE之数组

    语法及元素访问 一些错误方式 数组的遍历(重点) Foreach循环写法 数组的排序(重点) 经典练习 非重点 二...

  • 2018-09-21

    关于数组 @(JavaSE) 数组平时用的太频繁了,可能就是因为用的太多,竟然根本就没有想过数组其实也是对象。任何...

网友评论

      本文标题:JavaSE进阶三 数组

      本文链接:https://www.haomeiwen.com/subject/qxgqsltx.html