第十五天 陣列

蘇豆發表於2021-01-03

概述

  1. 陣列型別: java中的陣列是一種引用資料型別,不屬於基本資料型別
  2. 陣列父類:Object
  3. 理解陣列:陣列就是一個容器,可以同時容納多個元素(陣列是一堆資料的集合)
  4. 儲存型別:儲存陣列中可以儲存基本資料型別的資料,也可以儲存引用資料型別的資料
  5. 儲存“java物件”:陣列中如果儲存但是"Java物件"的話,實際上儲存的是該物件的“引用(記憶體地址)”,而不是Java物件,陣列是不能直接儲存java物件的
  6. 長度變化:Java語言中的陣列一旦建立,長度是不能改變的
  7. 元素個數:所有的陣列物件都有length屬性,用來獲取陣列中元素的個數
  8. 元素統一Java中的陣列要求陣列中的元素型別統一
  9. 陣列分類:一維陣列、二維陣列、多維陣列…
  10. 儲存特點:陣列在記憶體方面儲存的時候,陣列中的記憶體地址的連續的
  11. 記憶體地址:所有陣列都是用陣列的第零個元素的記憶體地址作為整個陣列物件的記憶體地址(因為陣列中的記憶體地址是連續的,所以有了第一個後面的元素的記憶體地址都可以算出來)
  12. 陣列下標:陣列中每一個元素都是有下標的,從0開始,以1遞增,最後一個元素的下標的是:length - 1

一維陣列

優缺點
  • 優點 : 查詢、檢索某個下標上的元素的時候效率極高
    • 每一個元素的記憶體地址在空間上是連續的
    • 每一個元素型別相同,所以佔用空間大小一樣
    • 知道第一個記憶體地址,知道元素佔用空間大小,知道下標,所以就可以數學表示式計算得出某個想下標的記憶體地址
  • 缺點:
    • 隨機增刪元素的效率極低
      • 因為陣列中元素的記憶體地址連續,所以在進行增刪操作的時候會涉及到後面所有元素的位移
      • 對於陣列的最後一個元素的增刪操作是沒有效率影響的
    • 陣列不能儲存大資料量
      • 因為很難在記憶體空間找到一塊特別大的連續記憶體空間
初始化
  • 如何宣告或定義一個一維陣列
    • 語法格式:陣列型別 [ ] 陣列名;
int[ ] array1;
double[ ] array2;
boolean[ ] array3;
String [ ] array4;
Object[ ] array5;
  • 初始化
  1. 靜態初始化
int[ ] array = {100, 200, 300};
  1. 動態初始化
int[ ] array = new int[5]
  • 初始化方式的選擇
    • 靜態初始化
      • 建立陣列的時候,可以確定陣列中儲存具體元素的時候
    • 動態初始化
      • 建立陣列的時候,不知道陣列中儲存的元素的時候,預先分配記憶體空間
對元素進行訪問
  • 例項
package Day14陣列;

public class Test01 {
    public static void main(String[] args) {
        // 靜態初始化一個int型別的陣列
        int[] array = {1, 2, 3, 4, 5};

        // 所有陣列物件都有的length屬性
        System.out.println("陣列元素個數為:" + array.length);

        // 通過下標讀取陣列中的元素
        System.out.println("第一個元素是:" + array[0]);
        System.out.println("最後的元素是:" + array[array.length - 1]);

        // 通過下標改變陣列中的元素
        array[0] = 9;
        array[array.length - 1] = 10;
        System.out.println("新的第一個元素是:" + array[0]);
        System.out.println("新的最後的元素是:" + array[array.length - 1]);
    }
}
遍歷
package Day14陣列;

public class Test02 {
    public static void main(String[] args) {
        // 動態初始化一個長度為10的一維陣列
        int[] array = new int[3];
        // 從第一位元素到最後一位的遍歷
        for (int i = 0; i < array.length; i++) {
            System.out.println("陣列中下標為" + i + "的元素為:" + array[i]);
        }

        // 動態初始化一個Object型別的陣列
        Object[] array2 = new Object[3];
        // 遍歷輸出array2的元素
        for (int i = 0; i < array2.length; i++) {
            System.out.println("陣列中下標為" + i + "的元素為:" + array2[i]);
        }

    }
}
方法的引數是陣列
package Day14陣列;

public class Test03 {
    public static void main(String[] args) {
        String[] strArray = {"張三", "李四", "王五", "趙六"};
        m1(strArray);

        int[] intArray = {1, 3, 3, 4};
        Test03 test03 = new Test03();
        test03.m2(intArray);

        //直接傳入一個String陣列
        m1(new String[]{"CCTV", "BBC", "NBA"});
    }

    // 靜態方法
    public static void m1(String[] strArray){
        for (int i = 0; i < strArray.length; i++) {
            System.out.println(strArray[i]);
        }
    }

    // 例項方法
    public void m2(int[] intArray){
        //增強for迴圈
        for (int i : intArray){
            System.out.println(i);
        }
    }
}
main方法中的陣列
  • main中法中的陣列:String[] args 有什麼用?
    • JVM在呼叫main方法的時候,會自動傳String陣列
  • 例項:
package Day14陣列;

public class Test05 {
    public static void main(String[] args) {
        if(args.length != 2){
            System.out.println("請輸入登入資訊:");
        }

        String username = args[0];
        String password = args[1];

        if ("admin".equals(username) && "123456".equals(password)){
            System.out.println("歡迎使用者:" + username + " 回來!");
        } else {
            System.out.println("登入失敗");
        }

    }
}

在這裡插入圖片描述

在這裡插入圖片描述

儲存引用資料型別
package Day14陣列;

public class Test04 {
    public static void main(String[] args) {
        //使用多型建立Cat、Dog物件
        Animal cat = new Cat();
        Animal dog = new Dog();

        //使用靜態初始化建立一個陣列接收
        Animal[] animals = {cat, dog};
        //遍歷Animal陣列
        for (Animal animal : animals){
            //因為子類繼承父類的move方法,所以根據方法覆蓋機制,呼叫的是子類的方法
            animal.move();
        }

        System.out.println("===========分割線===========");

        //初始化Cat和Dog物件
        Dog dog1 = new Dog();
        Cat cat1 = new Cat();

        // 使用動態初始化建立一個陣列
        Animal[] animals1 = new Animal[2];
        //因為dog和cat都是Animal的子類,所以能放在Animal型別的陣列中
        animals1[0] = cat1;
        animals1[1] = dog1;

        for (Animal animal : animals1){
            //呼叫子類中特有的方法
            if (animal instanceof Cat){
                ((Cat) animal).catchMouse();
            }

            if (animal instanceof Dog){
                ((Dog) animal).bark();
            }
        }


    }

}

class Animal{
    public void move(){
        System.out.println("動物在移動");
    }
}

class Cat extends Animal{
    @Override
    public void move() {
        System.out.println("貓貓在走貓步");
    }

    public void catchMouse(){
        System.out.println("貓抓老鼠");
    }
}

class Dog extends Animal{
    @Override
    public void move() {
        System.out.println("狗狗在跳躍");
    }

    public void bark(){
        System.out.println("犬吠");
    }
}
陣列擴容、拷貝
  • 一維陣列的擴容問題,因為在java中,陣列長度一旦確定,就不可變,那如果陣列滿了,還需要向陣列存放元素該怎麼辦?
    • java對陣列擴容的方法是:先新建一個大容量的陣列,然後將小容量陣列中的陣列全部拷貝到大容量資料中
  • 結論:
    • 陣列擴容效率極低,因為涉及到了拷貝方面的問題
    • 所以在開發的時候要儘可能的減少陣列擴容
    • 在建立陣列物件的時候就預計以下多長比較適合
  • 如何進行陣列拷貝?
  • 陣列拷貝原始碼:
//      原始碼:
        public static native void arraycopy(Object src, int srcPos, Object dest, int destPos,int length);

/* 五個引數的含義
拷貝源
拷貝源的起始位置
拷貝目標
拷貝目標的起始位置
長度
*/

  • 例項
package Day14陣列;

public class Test06 {
    public static void main(String[] args) {

        int[] src = {1, 2, 3, 4, 5};    //拷貝源

        int[] srcPos = new int[20];     //拷貝目標

        //使用JDK System中的arraycopy方法進行拷貝
        System.arraycopy(src, 1, srcPos, 1, 3);

        //遍歷輸出原陣列
        System.out.println("原陣列:");
        for (int i : src){
            System.out.print(i + ",");
        }

        System.out.println();

        //遍歷輸出新的陣列,檢視拷貝情況
        System.out.println("新陣列:");
        for (int i : srcPos){
            System.out.print(i + ",");
        }

        System.out.println();

        //將原陣列中的內容全部拷貝過去
        System.arraycopy(src, 0, srcPos, 0, 5);

        //遍歷原陣列
        System.out.println("原陣列:");
        for(int i : src){
            System.out.print(i + ",");
        }

        System.out.println();

        //遍歷輸出新陣列
        System.out.println("新陣列:");
        for (int i : srcPos){
            System.out.print(i + ",");
        }

        System.out.println();

        //原陣列中儲存的是字串
        String[] src2 = {"張三", "李四", "王五"};
        System.out.println("原陣列:");
        for (String str : src2){
            System.out.print(str + ",");
        }
        System.out.println();
        String[] src2Pos = new String[5];
        System.arraycopy(src2, 0, src2Pos, 0, src2.length);
        System.out.println("新陣列:");
        for (String str : src2Pos){
            System.out.print(str + ",");
        }

        System.out.println();

        //原陣列中儲存的是物件
        Object[] src3 = {new Object(), new Object(), new Object()};
        System.out.println("原陣列:");
        for (Object obj : src3){
            System.out.println(obj);
        }
        Object[] src3Pos = new Object[5];
        System.arraycopy(src3, 0, src3Pos, 0, src3.length);
        System.out.println("新陣列:");
        for (Object obj : src3Pos){
            System.out.println(obj);
        }

    }
}

二維陣列

概述
  • 二維陣列其實就是一個特殊的一維陣列
    • 特殊之處:二維陣列中的每一個元素都是一個一維陣列
  • 靜態初始化:
int array[ ][ ] = {{ }, { }, { }}
  • 例項
package Day14陣列;

public class Test07 {
    public static void main(String[] args) {
        int[][] array = {
                {1, 2, 3},
                {3, 2, 1},
                {1, 2, 3, 4, 5, 6, 7}
        };
    }
}
二維陣列的length屬性
  • 二維陣列的length屬性是指陣列中一維陣列的個數
  • 例項
package Day14陣列;

public class Test08 {
    public static void main(String[] args) {
        int[][] array = {
                {1, 2, 3},
                {3, 2, 1},
                {1, 2, 3, 4, 5, 6, 7}
        };

        //輸出二維陣列的長度
        System.out.println(array.length);

        //輸出二維陣列第一個元素的長度
        System.out.println(array[0].length);

        //輸出二維陣列第三個元素的長度
        System.out.println(array[2].length);
    }
}
二維陣列的元素訪問
  • 語法
陣列名[二維陣列中的一維陣列下標][一維陣列的下標]
  • 例項
package Day14陣列;

public class Test09 {
    public static void main(String[] args) {
        int[][] array = {
                {1, 2, 3},
                {3, 2, 1},
                {1, 2, 3, 4, 5, 6, 7}
        };

        //訪問二維陣列的第一個一維陣列的第一位
        System.out.println(array[0][0]);

        //訪問二維陣列的第三個一維陣列的第四位
        System.out.println(array[2][3]);
        
    }
}
二維陣列的遍歷
  • 使用兩個for迴圈進行遍歷
package Day14陣列;

public class Test10 {
    public static void main(String[] args) {
        int[][] array = {
                {1, 2, 3},
                {3, 2, 1},
                {1, 2, 3, 4, 5, 6, 7}
        };

        for (int[] arr : array){
            for (int i : arr){
                System.out.print(i + " ");
            }
            System.out.println();
        }
    }
}

相關文章