主頁 > 後端開發 > Java基礎語法(六)——陣列的定義與使用

Java基礎語法(六)——陣列的定義與使用

2021-04-20 11:20:22 後端開發

文章目錄

  • Java基礎語法(六)——陣列的定義與使用
  • 一、 陣列基本用法
  • 1.什么是陣列
  • 2. 創建陣列
  • 3.定義陣列的方式
  • 4. 陣列的使用
    • (1)獲取長度
    • (2)訪問陣列中的元素
    • (3)下標越界
    • (4)遍歷陣列
  • 5.陣列在記憶體中的存盤
  • 二、陣列作為方法的引數
  • 1.基本用法
  • 2.理解參考型別
    • (1)引數傳內置型別
    • (2)引數傳陣列型別
  • 3.認識 null
  • 4.初識JVM記憶體區域劃分
  • 三、陣列作為方法的回傳值
  • 四、陣列練習
    • 1.陣列轉字串
    • 2.陣列拷貝
    • 3. 找陣列中的最大元素
    • 4.求陣列中元素的平均值
    • 5.查找陣列中指定元素(順序查找)
    • 6.查找陣列中指定元素(二分查找)
    • 7.檢查陣列的有序性
    • 8.陣列排序(冒泡排序)
    • 9.陣列逆序
  • 五、二維陣列
    • 規則的二維陣列
    • (1)二維陣列的定義
    • (2)記憶體中的二維陣列
    • (3) 二維陣列的列印
    • 不規則的二維陣列
    • Java中不規則二維陣列的定義
    • (1)不規則二維陣列的定義
    • (2)記憶體中的二維陣列
    • (3)列印方式
  • 完!

本次內容介紹大綱

在這里插入圖片描述



接上篇博客 Java基礎語法(五)——方法的使用


Java基礎語法(六)——陣列的定義與使用


一、 陣列基本用法


1.什么是陣列


??陣列本質上就是讓我們能 “批量” 創建相同型別的變數.


例如:

如果需要表示兩個資料, 那么直接創建兩個變數即可 int a; int b

 int a = 10;
 int b = 20;

如果需要表示五個資料, 那么可以創建五個變數 int a1; int a2; int a3; int a4; int a5;

 int a1 = 10;
 int a2 = 20;
 int a3 = 30;
 int a4 = 40;
 int a5 = 50;

??但是如果需要表示一萬個資料, 那么就不能創建一萬個變數了. 這時候就需要使用陣列, 幫我們批量創建.

int[] array = {10,20,30,40,50};

上面就是整型陣列.

注意事項: 在 Java 中, 陣列中包含的變數必須是 相同型別.


2. 創建陣列

基本語法

在這里插入圖片描述

??在上面的實體中,我們就以整型陣列為例,創建了一個 int [ ] 型別的array陣列,并且存放了5個整形資料.講解了陣列創建時的用法,Java陣列的創建與C語言很是相似,但是還是有區別的.


C語言版本陣列的創建:

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

Java版本陣列的創建:

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

??我們可以通過兩種寫法看到其中的區別. Java當中一定要 [ ] 和資料型別緊挨在一起.

??陣列的資料在記憶體中是連續存放的.繼續以上面的代碼為例:

在這里插入圖片描述


??陣列的每一元素都有其對應的下標,而下標->從0開始,我們要想找到這個陣列中的某個資料,是通過陣列的下標來進行訪問的.


注意:

陣列也被稱為存放一組相同型別的資料的集合!!

下標是從0號位置開始的.


3.定義陣列的方式


定義方式一

在這里插入圖片描述

??上面我們寫的代碼是,定義并初始化了一個陣列.

在這里插入圖片描述
??這樣的方式才只是定義了一個陣列.這就是我們定義陣列的第一種方式.且這樣定義的陣列默認大小為0.


定義方式二

在這里插入圖片描述
??這樣也是定義了一個陣列,不過這個陣列定義是通過new 這樣一個關鍵字,給 array 分配了一塊記憶體,這塊記憶體有10個資料可以存放.

在這里插入圖片描述
??int [ 10 ] 分配的連續記憶體空間.

??不過此時,我們還未給 array 這個陣列進行初始化,所以 array 此時的這十個資料默認值為0.


定義方式三

在這里插入圖片描述

??在Java當中在已經初始化之后, = 左邊的 [ ] 中是不能填數字的, = 右邊的 [ ] 只有在 定義方式二 中可以給定值.


在定義方式三中

在這里插入圖片描述

總結定義陣列的三種方式:

 int[] array1 = {1,2,3,4,5}; // 定義一
 int[] array2 = new int[10];  //  定義二
 int[] array3 = new int[]{1,2,3,4,5}; // 定義三

在這三種方式中,Java中定義陣列最常用的是方式一,


4. 陣列的使用


(1)獲取長度


注意事項

  1. 使用 arr.length 能夠獲取到陣列的長度. . 這個操作為成員訪問運算子. 后面在面向物件中會經常用到

代碼示例:

  public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
        System.out.println(array.length);
    }

編譯結果:

在這里插入圖片描述


(2)訪問陣列中的元素


陣列訪問的方式:


在這里插入圖片描述

注意事項:

  1. 使用 [ ] 按下標取陣列元素. 需要注意, 下標從 0 開始計數
  1. 使用 [ ] 操作既能讀取資料, 也能修改資料.
  1. 下標訪問操作不能超出有效范圍 [0, length) , 如果超出有效范圍, 會出現下標越界例外

代碼示例:

public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
        
        //獲取陣列中的元素的個數
        //System.out.println(array.length);
        
        //訪問陣列中的元素
         System.out.println(array[1]); // 執行結果: 2
         System.out.println(array[2]); // 執行結果: 3
        
        //修改陣列中的元素 
        array[2] = 100; 
         
         System.out.println(array[2]); // 執行結果: 100
    }

編譯結果:

在這里插入圖片描述


(3)下標越界


??陣列下標從0開始,范圍是 [0,arr.length) ,左閉右開的區間,或者是[ 0,arr.length-1].

??如果我們將下標的值超出陣列的范圍…


如下所示

 public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        System.out.println(arr[100]);
    }

編譯結果:

在這里插入圖片描述

(4)遍歷陣列


??所謂 “遍歷” 是指將陣列中的所有元素都訪問一遍, 不重不漏. 通常需要搭配回圈陳述句


1.遍歷方式(一)-----for回圈

public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

編譯結果:

在這里插入圖片描述
??我們可以看到,用 for 回圈 將陣列中的元素一 一遍歷 并列印出來.


2.遍歷方式(二)---->for-each

??for-each 是 for 回圈的另外一種使用方式. 能夠更方便的完成對陣列的遍歷. 可以避免回圈條件和更新陳述句寫錯.

for-each 的基本使用

在這里插入圖片描述

代碼示例:

 public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        for (int x:arr) {
            System.out.print(x+" ");
        }
    }

編譯結果:

在這里插入圖片描述

for-each 遍歷的原理

??遍歷array 里面的每一個元素,把每一個元素取出來,然后賦值給了 x ,最后列印 x ,直到 array 里面的元素全部都遍歷完成.

兩種遍歷的方式我們介紹完了,那么for回圈和for-each有什么區別?

??for回圈是可以拿到陣列下標的,for-each拿不到陣列下標,所以for-each只能夠全部遍歷,無法對陣列元素進行修改或進行操作.


3.遍歷方式(三)——使用操作陣列的工具類進行陣列的列印

??Arrays 就是操作Java陣列的工具類,你要對陣列做什么事情,就可以通過他來做,當然有些事情他是完成不了的.

??比如說:我們要列印陣列,我們本來是用for回圈 或者 for-each 來寫的,但是我們也可以用Arrays的工具類列印.

??通過JDK的工具檔案,我們查找到了相應的工具類.

在這里插入圖片描述

在這里插入圖片描述

??好,我們對arr陣列進行操作如下:

  public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        System.out.println(Arrays.toString(arr));
    }

編輯結果:

在這里插入圖片描述


5.陣列在記憶體中的存盤


??我們在之前的博客已經很簡單介紹了Java中的記憶體區域劃分,那么今天我們認識了陣列這個參考型別,那么它在記憶體中如何進行存盤呢?


??我們先簡單回顧一下Java的記憶體區域

在這里插入圖片描述
??我們知道區域變數都在Java虛擬機堆疊上存放,而陣列的資料則在堆上進行存放, 陣列的資料在堆上都有特定的地址,而陣列的變數存放的其實是這組資料的地址,堆疊上的這個變數根據這個地址找到堆上的資料.


??陣列的具體存盤由下圖所示:

在這里插入圖片描述
注意點:

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
??上圖為arr指向的資料在堆中的地址,這個地址并不是真正的地址,它是通過正式的地址 hash 得到的.但是我們可以把它當作真實的地址,因為這個地址也是唯一的.

??那么真實的地址為什么要hash操作呢?

??這就是Java的安全性了,不會輕易暴露自己資料的地址.


二、陣列作為方法的引數


1.基本用法


代碼示例: 列印陣列內容

 public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        printArray(arr);
    }
    public static void printArray(int[] a) {
        for (int x : a) {
            System.out.println(x);
        }
    }

在這個代碼中

1.int [ ] a 是函式的形參, int [ ] arr 是函式實參.

2.如果需要獲取到陣列長度, 同樣可以使用 a.length


2.理解參考型別


??在上一期博客 方法的使用中 ,我們介紹了一個用方法來交換兩個變數 的具體情況.現在我們來回顧一下.


(1)引數傳內置型別


在這里插入圖片描述


??我們用 內置型別作為引數,進行交換變數,但是最后編譯的結果 兩個變數卻并未發生交換.

??這是為什么呢?

在這里插入圖片描述
??交換形參 的值, 不影響實參的 值.


(2)引數傳陣列型別


在這里插入圖片描述
??我們用 陣列作為引數,進行交換變數,編譯運行后,發現成功交換兩個變數的值,此時陣列名 arr 是一個 “參考” . 當傳參的時候, 是按照參考傳參.

??那么為什么傳參考型別可以 形參可對實參進行操作呢?

??這里我們就要先從記憶體說起

??在上面我們介紹了陣列在記憶體中的儲存,

在這里插入圖片描述

??我們可以知道,陣列這個在堆疊中存放的變數實際存放的是 堆中資料的地址,當我們 arr 陣列作為引數 傳入 方法里,我們就把 堆中資料的地址 傳入了進去,在方法內部,我們可以根據 這個地址 找到堆中的資料進而修改資料,從而實作了形參改變了實參的操作.


在這里插入圖片描述


總結:

??所謂的 “參考” 本質上只是存了一個地址. Java 將陣列設定成參考型別, 這樣的話后續進行陣列引數傳參, 其實只是將陣列的地址傳入到函式形參中. 這樣可以避免對整個陣列的拷貝(陣列可能比較長, 那么拷貝開銷就會很大).


3.認識 null


??參考型別的0值 就是 null.


在這里插入圖片描述
??當我們將 null 賦給arr 這個參考型別時,這又是什么意思呢?


代表 arr 這個參考,不指向任何物件.


??當我們運行這個代碼時,顯示的結果就是 null ,不是數值 0.


在這里插入圖片描述


??那我們再來看一個問題

??當我們將 null 賦給 arr 之后,那么arr 陣列的長度是多少呢?

??我們猜測可能為0,現在來運行代碼.

??運行結果如下:

在這里插入圖片描述


??此時,編輯器報錯,錯誤型別:空指標例外.

??好了,這時我們可以知道,null 賦給了 arr ,arr 沒有指向任何一個陣列物件,在堆上也沒有開辟記憶體空間,所以我們也就無法求它的長度.


總結:

null.任何東西,都會發生 空指標例外的錯誤.

經驗:只要以后出現這樣的例外,肯定是這一個參考是 null.


4.初識JVM記憶體區域劃分


一個宿舍樓會劃分成幾個不同的區域: 大一學生, 大二學生… 計算機專業學生, 通信專業學生…


記憶體也是類似, 這個大走廊被分成很多部分, 每個區域存放不同的資料.

JVM 的記憶體被劃分成了幾個區域, 如圖所示:

在這里插入圖片描述


程式計數器 (PC Register):

只是一個很小的空間, 保存下一條執行的指令的地址.

虛擬機堆疊(JVM Stack):

重點是存盤區域變數表(當然也有其他資訊). 我們剛才創建的 int[] arr 這樣的存盤地址的參考就是在這里保存.

本地方法堆疊(Native Method Stack)

本地方法堆疊與虛擬機堆疊的作用類似. 只不過保存的內容是Native方法的區域變數. 在有些版本的 JVM 實作中(例如HotSpot), 本地方法堆疊和虛擬機堆疊是一起的.

堆(Heap):

JVM所管理的最大記憶體區域. 使用 new 創建的物件都是在堆上保存 (例如前面的 new int[]{1, 2, 3} )

方法區(Method Area):

用于存盤已被虛擬機加載的類資訊、常量、靜態變數、即時編譯器編譯后的代碼等資料. 方法編譯出的的位元組碼就是保存在這個區域.

運行時常量池(Runtime Constant Pool):

是方法區的一部分, 存放字面量(字串常量)與符號參考. (注意 從JDK1.7 開始, 運行時常量池在堆上)

??關于上面的劃分方式, 我們隨著后面的學習慢慢理解. 此處我們重點理解 虛擬機堆疊 和 堆.

在這里插入圖片描述

1.區域變數和參考保存在堆疊上, new 出的物件保存在堆上.

2.堆的空間非常大, 堆疊的空間比較小.

3.堆是整個 JVM 共享一個, 而堆疊每個執行緒具有一份(一個 Java 程式中可能存在多個堆疊).


三、陣列作為方法的回傳值


代碼示例:


   public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        transform(arr);
        printArray(arr);
    }
    public static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]); }
    }
    public static void transform(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] = arr[i] * 2; }
    }
    

??這個代碼固然可行, 但是破壞了原有陣列. 有時候我們不希望破壞原陣列, 就需要在方法內部創建一個新的陣列, 并由方法回傳出來,


??修改后的代碼:

  public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        int[] output = transform(arr);
        printArray(output);
    }
    public static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
    public static int[] transform(int[] arr) {
        int[] ret = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            ret[i] = arr[i] * 2;
        }
        return ret;
    }

??這樣的話就不會破壞原有陣列了.

??另外由于陣列是參考型別, 回傳的時候只是將這個陣列的首地址回傳給函式呼叫者, 沒有拷貝陣列內容, 從而比較高效,


四、陣列練習


1.陣列轉字串


題目要求:

實作一個方法 toString, 把一個整型陣列轉換成字串.

例如陣列 {1, 2, 3} , 回傳的字串為 “[1, 2, 3]”, 注意 逗號 的位置和數量.


  public static String mytoString(int[] arr){
        String ret = "[";
        for (int i = 0; i <arr.length ; i++) {
            if(i!=arr.length-1){
                ret+=arr[i]+",";
            }else if(i==arr.length-1){
                ret+=arr[i]+"]";
            }
        }
        return ret;
    }

    public static void main3(String[] args) {
        int[] arr ={1,5,6,78,7,87,8,5,45,4,12,12};
        //System.out.println(Arrays.toString(arr));
        System.out.println(mytoString(arr));
    }


2.陣列拷貝


陣列的拷貝方式


1.for回圈拷貝

  //陣列拷貝

    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        int[] copy = new int[arr.length];
        for (int i = 0; i <arr.length ; i++) {
            copy[i] = arr[i];
        }
        System.out.println(Arrays.toString(copy));
    }

??在這種拷貝方式中,我們首先通過 new 一個新的和 arr 一樣長度陣列 copy,再通過 for 回圈將 arr 陣列中的內容 一 一賦給copy陣列,達到 最終的陣列拷貝的效果.


2.Arrays陣列的工具類

(1)copyOf()

我們先通過JKD的工具檔案,來看一下拷貝工具的用法

在這里插入圖片描述
功能:復制指定的陣列,用零截取或填充(如有必要),以便復制具有指定的長度.

具體看一下Java當中copyOf方法的具體實作

在這里插入圖片描述
??首先 Arrays.copyOf() 的回傳型別是 int [ ] ,第一個引數是 原陣列(要拷貝的陣列),第二個引數是新陣列的長度(可以自己定),如果新的陣列的長度比原陣列長的話,大于原陣列長度的元素都補為0 , 具體如下所示…

在這里插入圖片描述

(2)copyOfRange()

我們先通過JDK檔案來查看這個工具類的功能


在這里插入圖片描述
功能:將指定陣列的指定范圍復制到新的陣列中.

具體看一下Java當中copyof方法的具體實作


在這里插入圖片描述


??copyOfRange 方法的回傳型別是 int [ ] ,第一個引數是 原陣列 ,第二、三引數是要拷貝原陣列資料的下標 ,一定要切記 是左閉右開的區間 , [ from , to ).


代碼示例

在這里插入圖片描述

3.System.arraycopy

在這里插入圖片描述
??我們打開 System.arraycopy 方法的具體實作,發現沒有和上面幾種拷貝方法的實作程序,System.arraycopy 有前面的 native 可知,這是一個本地方法,


本地方法

1.運行在本地方法堆疊上

2.底層是由C/C++代碼實作的


??System.arraycopy 沒有回傳值,第一個引數原陣列(要拷貝的陣列),第二個引數是原始陣列要拷貝的下標,第三個引數是目的地陣列 ,第四個引數是 目的地陣列的下標,第五個陣列是要拷貝的長度.


代碼示例:

在這里插入圖片描述
注意點:


??System.arraycopy 最后一個引數 ——要拷貝的陣列長度,這個資料不能超過原陣列的長度,否則編輯器會發生錯誤報告:陣列越界,


  1. 陣列名.clone ----> 產生當前陣列的一個副本

功能: 產生一個當前陣列的一個副本,


代碼示例:

在這里插入圖片描述

3. 找陣列中的最大元素


題目內容:

給定一個整型陣列, 找到其中的最大元素 (找最小元素同理)

代碼實作:

public static int findMax(int[] arr){

        int max = arr[0];

        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        
        return max;

    }

    public static void main(String[] args) {
        int[] arr={10,20,900,40,100,500};
        int ret = findMax(arr);
        System.out.println(ret);
    }

4.求陣列中元素的平均值


題目內容

給定一個整型陣列, 求平均值

代碼實作:

 public static double aver(int[] arr){
        int sum = 0;
        for (int i = 0; i <arr.length ; i++) {
            sum += arr[i];
        }
        double average = (sum*1.0)/arr.length;
        return average;
    }

    public static void main(String[] args) {
        int[] arr = {1,2,8,4,5};
        double ret = aver(arr);
        System.out.println(ret);
    }

注意點:

??最后求 aver 方法中平均值 average 時 sum要記得 sum * 1.0,這樣算出的平均值才是 double 型別的資料,


5.查找陣列中指定元素(順序查找)


題目內容

給定一個陣列, 再給定一個元素, 找出該元素在陣列中的位置.

代碼實作

  public static int toFind(int[] arr,int key){
        for (int i = 0; i <arr.length ; i++) {
            if(key==arr[i])
                return i;
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        System.out.println(toFind(arr, 3));

    }


6.查找陣列中指定元素(二分查找)


針對有序陣列, 可以使用更高效的二分查找.

什么叫有序陣列?

有序分為 “升序” 和 “降序” 如 1 2 3 4 , 依次遞增即為升序. 如 4 3 2 1 , 依次遞減即為降序.

??以升序陣列為例, 二分查找的思路是先取中間位置的元素, 看要找的值比中間元素大還是小. 如果小, 就去左邊找; 否則就去右邊找.

代碼實作:

 public static int binarySearch(int[] arr,int key){
        int i = 0;
        int j = arr.length-1;
        while(i<=j){
            int mid = (i+j)/2;
            if(arr[mid]==key){
                return mid;
            }else if(arr[mid]>key){
                j=mid-1;
            }else if(arr[mid]<key){
                i=mid+1;
            }
        }
        //從回圈里跳出時還未找到要查找的數字,回傳-1(不能是陣列下標的值)
        return -1;
    }

    public static void main2(String[] args) {
        int[] arr = {1,2,3,4,5,6,77,9};
        int ret = binarySearch(arr,1);
        System.out.println("查找數字的下標是"+ret);
    }



??二分查找的具體思路可以到我的往期博客——有序陣列中查找具體數字n(二分查找)了解詳情,


7.檢查陣列的有序性


題目內容

給定一個整型陣列, 判斷是否該陣列是有序的(升序)

代碼實作:

  public static boolean isSorted(int[] array){
        if(array==null){
            return false;
        }
        for (int i = 0; i <array.length-1 ; i++) {
            if(array[i+1]<array[i]){
                return false;
            }
        }
        return true;

    }

    public static void main1(String[] args) {
        int[] array = null;
        System.out.println(isSorted(array));

    }


注意點:

要記得檢查傳入陣列是否為 null ,如果傳入的 arr 陣列為 null ,此時回傳 false 型別,


8.陣列排序(冒泡排序)


題目內容

給定一個陣列, 讓陣列升序 (降序) 排序.

演算法思路

每次嘗試找到當前待排序區間中最小(或最大)的元素, 放到陣列最前面(或最后面).

代碼實作:

  public static void main1(String[] args) {
        int[] array = {10,51,20,14,64,54};
        bubbleSort(array);
        System.out.println(Arrays.toString(array));
    }

    public static void bubbleSort(int[] array){
        boolean flg = false;

        for (int i = 0; i <array.length-1 ; i++) {
            for(int j = 0;j<array.length-1-i;j++){
                if(array[j]>array[j+1]){
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                    flg= true;
                }
            }
            if(!flg)
                break;
        }

    }

??冒泡排序的具體詳解可以到我的往期博客——排序演算法之冒泡排序查看,這里就不過多介紹,


9.陣列逆序


題目內容

給定一個陣列, 將里面的元素逆序排列.

思路

設定兩個下標, 分別指向第一個元素和最后一個元素. 交換兩個位置的元素.

然后讓前一個下標自增, 后一個下標自減, 回圈繼續即可

代碼實作:

  public static void reverse(int[] arr){
        int left =0;
        int right =arr.length-1;
        while(left<=right){
            int tmp = arr[left];
            arr[left] = arr[right];
            arr[right] = tmp;
            left++;
            right--;
        }
    }

    public static void main(String[] args) {
        int[] arr= {1,2,3,4,5,6,7};
        reverse(arr);
        System.out.println(Arrays.toString(arr));
    }

五、二維陣列


??二維陣列本質上也就是一維陣列, 只不過每個元素又是一個一維陣列.


規則的二維陣列


(1)二維陣列的定義

在這里插入圖片描述

(2)記憶體中的二維陣列


??以上面的 int [ 2 ][ 3 ]為例

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

在這里插入圖片描述
??我們之前說過二維陣列本質上是一個特殊的一維陣列,

??這個陣列的每一行 arr [0] 、arr [1] ,構成了一個一維陣列,每一行存放著指向每一列資料的地址,

?? 每一列也是一個單獨的一維陣列,指向堆中的每一個資料,


(3) 二維陣列的列印


??知道了二維陣列在記憶體中的存放與指向,所以我們知道 arr.length 得出的就是 行的個數 , arr [ i ].length 得出的就是 列的個數,


  1. for 回圈列印

??我們對 這個二維資料進行 for 回圈 列印,


代碼示例:

 public static void main(String[] args) {
        int[][] arr = {{1,2,3},{4,5,6}};
        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();
        }
    }

列印結果:

在這里插入圖片描述


  1. for-each 列印

如果我們用 for-each 列印,代碼示例:

 public static void main(String[] args) {
        int[][] arr = {{1,2,3},{4,5,6}};
        for (int[] array:arr) {
            for (int x:array) {
                System.out.print(x+" ");
            }
            System.out.println();
        }
    }

列印結果如下:

在這里插入圖片描述


  1. Arrays 工具類 列印

??在一維陣列中,我們想要將陣列轉化為字串列印用的是 Arrays.toString ( ) ,那么二維陣列轉化為字串的工具類是什么呢?

??如果我們用 Arrays.toString ( ) 進行列印

在這里插入圖片描述


??結果列印的是 arr 行代表的陣列內容——列代表的一維陣列的地址,顯而易見 Arrays.toString ( ) 無法列印出二維陣列的全部內容,


我們查找 JDK 檔案發現了 deepToString( ) 工具類,

在這里插入圖片描述
功能:回傳指定陣列的 “ 深度內容 ” 的字串表示形式,

我們用 deepToString()進行列印…

結果如下:

在這里插入圖片描述


成功列印出二維陣列的內容,

deepToString ( ) 可以正確的列印出二維陣列的全部資料,


不規則的二維陣列


在C語言中,我們定義二維陣列可以 只定義列,不用規定行的值,

C語言中陣列的定義

int[][2] = {1,2,3,4,5,6,7};

而在Java中我們只能 定義行,列不用規定值,

int[][] arr = new int[2][];

Java中不規則二維陣列的定義


??什么是不規則的二維陣列?

??在之前的規則的二維陣列中,每一行的資料個數都相同,列數也相同,而不規則的二維陣列,規定了行數,列數有我們自己定,每一行有多少列由我們自己規定,


(1)不規則二維陣列的定義

public static void main(String[] args) {
        int[][] arr = new int[2][];
        arr[0] = new int[]{1,2,3};
        arr[1] = new int[]{4,5};
        System.out.println(Arrays.deepToString(arr));
    }

編譯結果:

在這里插入圖片描述

首先我們規定了一個 有兩行的二維陣列

int [ ] [ ] arr = new int [2] [ ];

我們自己給每一行的陣列規定有多少列,

arr [ 0 ] = new int [ ] { 1,2,3 }
arr [ 1 ] = new int [ ] { 4,5 };

這就是不規則的二維陣列的定義,


(2)記憶體中的二維陣列

在這里插入圖片描述

與規則的二維陣列記憶體存盤基本相同,


(3)列印方式


??不規則的二維陣列列印方式同規則二維陣列列印方式一樣,




??最后,同理, 還存在 “三維陣列”, “四維陣列” 等更復雜的陣列, 只不過出現頻率都很低,




??好了,這次的Java基礎語法——陣列的定義與使用的知識就分享到這里,感謝大家的欣賞與關注!!




謝謝欣賞!!





完!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/278073.html

標籤:java

上一篇:SpringBoot整合MybatisPlus【超詳細】

下一篇:手把手教學妹CompletableFuture異步化,性能關系直接起飛!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more