Java語法 | 多維數組

前言

C: 上一篇,咱們學習了數組的概念,並掌握了它的定義及基本使用方法。java

下面,咱們再來看一個案例需求。算法

案例需求:已知有3個班級各5名學員,請計算各個班級的總成績。數組

根據需求及經驗來分析,若是咱們只是要計算單個班級的學生總成績,那麼定義一個普通數組,來存儲這些成績信息,再去計算便可。微信

// 存儲一個班成績
double[] scores = new double[5];
// ...
複製代碼

而如今須要計算三個班級的各自總成績,按經驗推導,應該先以下定義存儲結構,而後分別計算。markdown

// 存儲第一個班成績
double[] scores1 = new double[5];
// 存儲第二個班成績
double[] scores2 = new double[5];
// 存儲第三個班成績
double[] scores3 = new double[5];
// ...
複製代碼

天然它也是能夠實現需求的。可是,在本篇,查老師將帶你學習一種更爲高級的方式:多維數組。數據結構

我這有本祕笈

概述

上一篇,咱們學的用來存儲多個數據的數組,它們被稱爲一維數組。數據結構和算法

多維數組,相似於前面學過的嵌套 if、嵌套循環。查老師以爲,你也能夠把多維數組稱之爲 "嵌套數組"。工具

它的常見表現形式有:二維數組、三維數組。oop

二維數組:是以 一維數組 做爲 數組元素 的數組,即 「數組的數組」。[1]學習

三維數組:是以 二維數組 做爲 數組元素 的數組。

有點拗口,定義向繞口令同樣,分明就是 "俄羅斯套娃" 麼。

image-20210117112857482

不過在使用多維數組前,須要再強化些概念理解:

  • 通常來說,主要使用的是二維數組,三維及以上使用較少( 本篇查老師也主要介紹二維數組的使用
  • 從語法上來看,Java 支持多維數組的寫法
  • 從內存分配原理的角度上來看,它們都是一維數組而已

定義

方式一

傳統的一維數組的聲明和賦值方式,咱們都是掌握的:

// 聲明語法:數據類型[] 數組名 = new 數據類型[數組容量];
// 例如:存儲5名學生成績:
// 數組存儲的元素:成績
// 數組元素的數據類型:double
// 數組的容量(要存儲的成績數量):5
double[] scores = new double[5];

// 賦值語法:數組名[下標] = 元素值;
scores[0] = 90;
scores[1] = 80;
scores[2] = 70;
scores[3] = 60;
scores[4] = 50;
複製代碼

image-20210117121736583

二維數組本質上就是一維數組,只不過是以 一維數組 做爲 數組元素 的數組。咱們能夠把二維數組分紅外維數組及內維數組。

// 聲明二維數組
// 語法
數據類型[][] 數組名 = new 數據類型[外維數組容量][內維數組容量];

// 給二維數組賦值
// 語法
數組名[外維數組下標][內維數組下標] = 元素值;
複製代碼

咱們結合着二維數組的語法,來初步實現下前言中的需求。

案例需求:存儲3個班各5名學生成績。

思路分析:

  1. 根據需求,因爲要存儲的兩組數據有包含關係,採用二維數組更爲合適

  2. 肯定數組的各個組成

    1. 外維數組:

      • 數組元素:班級

      • 數組元素類型:double[]

      • 數組容量:5

    2. 內維數組:

      • 數組元素:成績
      • 數組元素類型:double
      • 數組容量:3
  3. 根據數組組成,套用方式一的數組語法實現

// 聲明一個二維數組 
double[][] scores = new double[3][5];

// 給二維數組賦值
// 第1個班
scores[0][0] = 90; // 第1個班的第1個同窗成績爲90
scores[0][1] = 80;
scores[0][2] = 70;
scores[0][3] = 60;
scores[0][4] = 50;
// 第2個班
scores[1][0] = 90;
scores[1][1] = 90;
scores[1][2] = 80;
scores[1][3] = 70;
scores[1][4] = 65;
// 第3個班
scores[2][0] = 85;
scores[2][1] = 70;
scores[2][2] = 75;
scores[2][3] = 80;
scores[2][4] = 60;
複製代碼

image-20210117123806149

查老師有話說: 雖然數組有些特別,不像以前學的基本數據類型:int、double..。但數組也是一種數據類型,因此 "別拿豆包不當乾糧,別拿數組不當數據類型" 。

方式二

在定義二維數組時,內維數組容量不是必須馬上指定的,還能夠這樣寫。

數據類型[][] 數組名 = new 數據類型[外維數組容量][內維數組容量];
複製代碼

案例需求:存儲三個班學生成績,1班有5個學生,2班有3個學生,3班有2個學生。

// 聲明一個二維數組
double[][] scores = new double[3][];
// 聲明內維數組
scores[0] = new double[5]; // 第一個班
scores[1] = new double[3]; // 第二個班
scores[2] = new double[2]; // 第三個班

// 賦值語法:數組名[外維數組下標][內維數組下標] = 元素值;
// 第1個班
scores[0][0] = 90;
scores[0][1] = 80;
scores[0][2] = 70;
scores[0][3] = 60;
scores[0][4] = 50;
// 第2個班
scores[1][0] = 90;
scores[1][1] = 90;
scores[1][2] = 80;
// 第3個班
scores[2][0] = 85;
scores[2][1] = 70;
複製代碼

image-20210117124857014

方式三

一維數組能夠在聲明時,實現直接賦值,二維數組天然也是能夠的。

// 存儲3個班各5名同窗成績
// 每一個 {} 就是一個一維數組
double[][] scores = {{90, 80, 70, 60, 50}, {90, 90, 80, 70, 65}, {85, 70, 75, 80, 60}};
複製代碼

另外它也支持下方的寫法:

double[][] scores = new double[][]{{90, 80, 70, 60, 50}, {90, 90, 80, 70, 65}, {85, 70, 75, 80, 60}};
複製代碼

動態賦值及遍歷

一維數組學習的時候,咱們發如今數組賦值時是重複性、有規律性的。當時咱們就用 Scanner 結合循環來優化了一下賦值過程,這樣就擁有了動態賦值的能力。

如今二維數組賦值雖然更爲複雜,可是依然保有重複性、規律性,咱們也能夠用 Scanner 結合循環來優化一下。

image-20210117133258901

思路分析:

  1. 根據效果圖分析,它分別有兩個規律性操做,採用二重循環
    • 班級的規律
    • 每一個班級的規律
  2. 循環要素
    1. 外層循環
      • 循環條件:< 外維數組的容量
      • 循環操做:內層循環
    2. 內層循環
      • 循環條件:< 內維數組的容量
      • 循環操做: 數組名[外層循環變量][內層循環變量] = 輸入的元素值;
  3. 固定次數循環,採用 for 循環
  4. 檢查循環是否能夠正常退出
double[][] scores = new double[3][5];

Scanner input = new Scanner(System.in);
// 循環班級
for (int i = 0; i < scores.length; i++) {
    // 循環每一個班級
    System.out.println("開始錄入第" + (i+1) + "個班的學生成績:");
    for (int j = 0; j < scores[i].length; j++) {
        System.out.print("請輸入" + (i+1) + "班的第" + (j+1) + "個學生的成績:");
        scores[i][j] = input.nextDouble();
    }
}
複製代碼

上述代碼就是二維數組的動態賦值方式。若是去除輸入賦值環節後,它顯然又是二維數組的遍歷方式。

double[][] scores = {{90, 80, 70, 60, 50}, {90, 90, 80, 70, 65}, {85, 70, 75, 80, 60}};

// 循環班級
for (int i = 0; i < scores.length; i++) {
    // 循環每一個班級
    System.out.println((i+1) + "班的學生成績以下:");
    for (int j = 0; j < scores[i].length; j++) {
        System.out.println("第" + (j+1) + "個學生的成績是:" + scores[i][j]);
    }
}
複製代碼

控制檯輸出:

1班的學生成績以下:
第1個學生的成績是:90.0
第2個學生的成績是:80.0
第3個學生的成績是:70.0
第4個學生的成績是:60.0
第5個學生的成績是:50.0
2班的學生成績以下:
第1個學生的成績是:90.0
第2個學生的成績是:90.0
第3個學生的成績是:80.0
第4個學生的成績是:70.0
第5個學生的成績是:65.0
3班的學生成績以下:
第1個學生的成績是:85.0
第2個學生的成績是:70.0
第3個學生的成績是:75.0
第4個學生的成績是:80.0
第5個學生的成績是:60.0
複製代碼

查老師有話說: 一維數組的時候,咱們有兩種遍歷方式:1.循環下標遍歷 2.加強 for循 環遍歷。而二維數組的話,查老師建議你就採用循環下標方式便可,不要再去 "混合或者自造語法" 了。

使用

好了,介紹完二維數組的概念和定義方式,接下來咱們完整的使用它,來完成前言中的案例需求。

案例需求:已知有3個班級各5名學員,請使用二維數組計算各個班級的總成績。

double[][] scores = {{90, 80, 70, 60, 50}, {90, 90, 80, 70, 65}, {85, 70, 75, 80, 60}};

// 循環班級
// 定義變量,記錄每一個班的總成績
double sum;
for (int i = 0; i < scores.length; i++) {
    // 每次都要初始化總成績
    sum = 0; 
    // 循環每一個班級
    for (int j = 0; j < scores[i].length; j++) {
        // 累加成績
        sum += scores[i][j];
    }
    System.out.println((i+1) + "班的學生總成績爲:" + sum);
}
複製代碼

控制檯輸出:

1班的學生總成績爲:350.0
2班的學生總成績爲:395.0
3班的學生總成績爲:370.0
複製代碼

Arrays工具類

有了數組以後,咱們就能夠實現很是多的算法需求。但不少算法需求中,部分功能都是相似的,咱們重複的實現,重複的寫。

例如:遍歷輸出數組的全部內容。

String[] arr = {"佩奇", "喬治", "蘇西"};
// 循環下標來實現數組遍歷
for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
}
複製代碼

而這一切,Java 創造團隊們也考慮到了,他們給咱們在 Java 類庫中提供了一個工具類:Arrays。在這個類中,提供的都是操做數組的方法。

方法名稱 說明
toString(array) : String 將一個數組 array 轉換成一個字符串
equals(array1,array2) : boolean 比較 array1 和 array2 兩個數組是否相等
sort(array) : void 對數組 array 的元素進行升序排列
copyOf(array,length) : newArray 把數組 array 複製成一個長度爲 length 的新數組,返回類型與複製的數組一致
... ...

它和咱們曾經使用過的 Scanner 都在 java.util 包下,因此使用的話也須要先導入一下。

查老師有話說: Java 系統類庫 java.util 包下的類都是工具類,使用前須要先 import。

看看下方,有了 Arrays,你只須要一行代碼,就能夠搞定一個數組的遍歷輸出操做。

package demo1;
// 1.導入 Arrays
import java.util.Arrays;

public class Demo1 {

    public static void main(String[] args) {
        String[] arr = {"佩奇", "喬治", "蘇西"};
        // 2.使用 Arrays(它不須要建立對象,直接能夠用)
        String arrStr = Arrays.toString(arr);
        System.out.println(arrStr); // [佩奇, 喬治, 蘇西]
    }

}
複製代碼

再例如:要比較兩個數組的內容是否相同。

char[] charArr1 = {'a', 'b', 'c', 'd'};
char[] charArr2 = {'a', 'b', 'c', 'd'};
// 不使用 equals 方法,原生寫法
boolean flag = true;
for (int i = 0; i < charArr1.length; i++) {
    if (charArr1[i] != charArr2[i]) {
        flag = false;
    }
}
System.out.println("兩個數組內容是否一致?" + flag);
複製代碼

而有了 Arrays,你只須要一行代碼,就能夠搞定兩個數組的內容比較操做。

char[] charArr1 = {'a', 'b', 'c', 'd'};
char[] charArr2 = {'a', 'b', 'c', 'd'};
boolean flag = Arrays.equals(charArr1, charArr2);
System.out.println("兩個數組內容是否一致?" + flag);
複製代碼

咱們再來看看另外兩個方法的使用示例。

// sort 方法
int[] arr1 = {10, 9, 11, 7, 8};
Arrays.sort(arr1);
System.out.println(Arrays.toString(arr1)); // [7, 8, 9, 10, 11]

// copyOf 方法
int[] arr2 = {10, 9, 11, 7, 8};
int[] newArr = Arrays.copyOf(arr2, arr2.length + 1);
System.out.println(Arrays.toString(newArr)); // [10, 9, 11, 7, 8, 0]
複製代碼

查老師有話說: Arrays 工具類還有更多的數組操做方法,等之後須要使用時,查老師再告訴你。或者在將來你有需求時,也能夠去查閱 Java 官方的 API 文檔,來挑選適合你的數組操做方法。

參考文獻

[1]百度百科. 二維數組[EB/OL]. baike.baidu.com/item/二維數組/8…. 2021.1.17

後記

好了,多維數組的介紹也就到這了,本篇的做業請微信搜索關注: 查老師的講義 ,而後回覆 多維數組做業 便可。

這一篇,我們還學到了一個 Arrays 工具類,是否是感受一些數組操做也沒那麼難了?的確,有了這類工具類的加入,將會更方便咱們平常的需求實現。

但也別忘了自身內功的提高,若是之後沒有合適的工具類,難道咱們就不能本身寫出來了嗎?

下一篇,咱們將圍繞數組進行一些排序算法學習,畢竟數據結構和算法不分家,算法中又以排序算法最爲經典,期待一下吧。

查老師有話說: 對於技術的學習,查老師一向遵循的步驟是:先用最最簡單的 demo 讓它跑起來,而後學學它的最最經常使用 API 和 配置讓本身能用起來,最後熟練使用的基礎上,在空閒時嘗試閱讀它的源碼讓本身可以洞徹它的運行機制,部分問題出現的緣由,同時借鑑這些技術實現來提高本身的代碼高度。

因此在查老師的文章中,前期基本都是小白文,僅僅穿插不多量的源碼研究。固然等小白文更新多了,大家還依然喜歡,後期會不定時專門對部分技術的源碼進行解析。

相關文章
相關標籤/搜索