Java數(shù)組(Array)最全匯總(中篇)
前言
本章是關(guān)于Java數(shù)組的最全匯總,本篇為匯總中篇,主要講了二維數(shù)組和不規(guī)則的數(shù)組的相關(guān)內(nèi)容。
數(shù)組是最常見的一種數(shù)據(jù)結(jié)構(gòu),它是相同類型的用一個(gè)標(biāo)識符封裝到一起的基本類型數(shù)據(jù)序列或者對象序列。
數(shù)組使用一個(gè)統(tǒng)一的數(shù)組名和不同的下標(biāo)來唯一確定數(shù)組中的元素。
實(shí)質(zhì)上,數(shù)組是一個(gè)簡單的線性序列,因此訪問速度很快。
本章將詳細(xì)介紹 Java 中數(shù)組的創(chuàng)建、初始化和處理方法,如獲取數(shù)組長度、查找數(shù)組元素和數(shù)組排序等。
本章學(xué)習(xí)要點(diǎn)
- 掌握一維數(shù)組的創(chuàng)建方法
- 掌握一維數(shù)組的初始化方法
- 熟練掌握一維數(shù)組的應(yīng)用
- 掌握二維數(shù)組的創(chuàng)建
- 掌握二維數(shù)組的初始化
- 熟練掌握二維數(shù)組元素的訪問方式
- 掌握數(shù)組的復(fù)制方法
- 掌握搜索數(shù)組元素的方法
- 掌握對數(shù)組的排序算法
Java二維數(shù)組詳解
為了方便組織各種信息,計(jì)算機(jī)常將信息以表的形式進(jìn)行組織,然后再以行和列的形式呈現(xiàn)出來。
二維數(shù)組的結(jié)構(gòu)決定了其能非常方便地表示計(jì)算機(jī)中的表,以第一個(gè)下標(biāo)表示元素所在的行,第二個(gè)下標(biāo)表示元素所在的列。
下面簡單了解一下二維數(shù)組,包括數(shù)組的聲明和初始化。
創(chuàng)建二維數(shù)組
在 Java 中二維數(shù)組被看作數(shù)組的數(shù)組,即二維數(shù)組為一個(gè)特殊的一維數(shù)組,其每個(gè)元素又是一個(gè)一維數(shù)組。
Java 并不直接支持二維數(shù)組,但是允許定義數(shù)組元素是一維數(shù)組的一維數(shù)組,以達(dá)到同樣的效果。聲明二維數(shù)組的語法如下:
type arrayName[][]; // 數(shù)據(jù)類型 數(shù)組名[][];
或
type[][] arrayName; // 數(shù)據(jù)類型[][] 數(shù)組名;
其中,type 表示二維數(shù)組的類型,arrayName 表示數(shù)組名稱,第一個(gè)中括號表示行,第二個(gè)中括號表示列。
下面分別聲明 int 類型和 char 類型的數(shù)組,代碼如下:
int[][] age;char[][] sex;
初始化二維數(shù)組
二維數(shù)組可以初始化,和一維數(shù)組一樣,可以通過 3 種方式來指定元素的初始值。這 3 種方式的語法如下:
type[][] arrayName = new type[][]{值 1,值 2,值 3,…,值 n}; // 在定義時(shí)初始化 type[][] arrayName = new type[size1][size2]; // 給定空間,在賦值 type[][] arrayName = new type[size][]; // 數(shù)組第二維長度為空,可變化
例 1
使用第一種方式聲明 int 類型的二維數(shù)組,然后初始化該二維數(shù)組。代碼如下:
int[][] temp = new int[][]{{1,2},{3,4}};
上述代碼創(chuàng)建了一個(gè)二行二列的二維數(shù)組 temp,并對數(shù)組中的元素進(jìn)行了初始化。圖 1 所示為該數(shù)組的內(nèi)存結(jié)構(gòu)。
圖1 二維數(shù)組內(nèi)存結(jié)構(gòu)
使用第二種方式聲明 int 類型的二維數(shù)組,然后初始化該二維數(shù)組。代碼如下:
int[][] temp = new int[2][2];
使用第三種方式聲明 int 類型的二維數(shù)組,并且初始化數(shù)組。代碼如下:
int[][] temp = new int[2][];
獲取單個(gè)元素
在上部分使用的前 2 種方式創(chuàng)建并初始化了一個(gè)二行二列的 int 類型數(shù)組 temp。
當(dāng)需要獲取二維數(shù)組中元素的值時(shí),也可以使用下標(biāo)來表示。語法如下:
arrayName[i-1][j-1];
其中,arrayName 表示數(shù)組名稱,i 表示數(shù)組的行數(shù),j 表示數(shù)組的列數(shù)。
例如,要獲取第二行第二列元素的值,應(yīng)該使用 temp[1][1]來表示。
這是由于數(shù)組的下標(biāo)起始值為 0,因此行和列的下標(biāo)需要減 1。
例 2
通過下標(biāo)獲取 class_score 數(shù)組中第二行第二列元素的值與第四行第一列元素的值。代碼如下:
public static void main(String[] args) { double[][] class_score = {{10.0,99,99},{100,98,97},{100,100,99.5},{99.5,99,98.5}}; System.out.println("第二行第二列元素的值:"+class_score[1][1]); System.out.println("第四行第一列元素的值:"+class_score[3][0]); }
執(zhí)行上述代碼,輸出結(jié)果如下:
第二行第二列元素的值:98.0 第四行第一列元素的值:99.5
獲取全部元素
在一維數(shù)組中直接使用數(shù)組的 length 屬性獲取數(shù)組元素的個(gè)數(shù)。
而在二維數(shù)組中,直接使用 length 屬性獲取的是數(shù)組的行數(shù),在指定的索引后加上 length(如 array[0].length)表示的是該行擁有多少個(gè)元素,即列數(shù)。
如果要獲取二維數(shù)組中的全部元素,最簡單、最常用的辦法就是使用 for 語句。
在一維數(shù)組全部輸出時(shí),我們使用一層 for 循環(huán),而二維數(shù)組要想全部輸出,則使用嵌套 for 循環(huán)(2 層 for 循環(huán))。
例 3
使用 for 循環(huán)語句遍歷 double 類型的 class_score 數(shù)組的元素,并輸出每一行每一列元素的值。代碼如下:
public static void main(String[] args) { double[][] class_score = { { 100, 99, 99 }, { 100, 98, 97 }, { 100, 100, 99.5 }, { 99.5, 99, 98.5 } }; for (int i = 0; i < class_score.length; i++) { // 遍歷行 for (int j = 0; j < class_score[i].length; j++) { System.out.println("class_score[" + i + "][" + j + "]=" + class_score[i][j]); } } }
上述代碼使用嵌套 for 循環(huán)語句輸出二維數(shù)組。
在輸出二維數(shù)組時(shí),第一個(gè) for 循環(huán)語句表示以行進(jìn)行循環(huán),第二個(gè) for 循環(huán)語句表示以列進(jìn)行循環(huán),這樣就實(shí)現(xiàn)了獲取二維數(shù)組中每個(gè)元素的值的功能。
執(zhí)行上述代碼,輸出結(jié)果如下所示。
class_score[0][0]=100.0 class_score[0][1]=99.0 class_score[0][2]=99.0 class_score[1][0]=100.0 class_score[1][1]=98.0 class_score[1][2]=97.0 class_score[2][0]=100.0 class_score[2][1]=100.0 class_score[2][2]=99.5 class_score[3][0]=99.5 class_score[3][1]=99.0 class_score[3][2]=98.5
例 4
假設(shè)有一個(gè)矩陣為 5 行 5 列,該矩陣是由程序隨機(jī)產(chǎn)生的 10 以內(nèi)數(shù)字排列而成。下面使用二維數(shù)組來創(chuàng)建該矩陣,代碼如下:
public class Test11 { public static void main(String[] args) { // 創(chuàng)建一個(gè)二維矩陣 int[][] matrix = new int[5][5]; // 隨機(jī)分配值 for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[i].length; j++) { matrix[i][j] = (int) (Math.random() * 10); } } System.out.println("下面是程序生成的矩陣\n"); // 遍歷二維矩陣并輸出 for (int k = 0; k < matrix.length; k++) { for (int g = 0; g < matrix[k].length; g++) { System.out.print(matrix[k][g] + ""); } System.out.println(); } } }
在該程序中,首先定義了一個(gè)二維數(shù)組,然后使用兩個(gè)嵌套的 for 循環(huán)向二維數(shù)組中的每個(gè)元素賦值。
其中,Math.random() 方法返回的是一個(gè) double 類型的數(shù)值,數(shù)值為 0.6、0.9 等,因此乘以 10 之后為 10 以內(nèi)的整數(shù)。
最后又使用了兩個(gè)嵌套的 for 循環(huán)遍歷二維數(shù)組,輸出二維數(shù)組中的值,從而產(chǎn)生矩陣。
運(yùn)行該程序的結(jié)果如下所示。
下面是程序生成的矩陣 78148 69230 43823 75663 05688
for each 循環(huán)語句不能自動(dòng)處理二維數(shù)組的每一個(gè)元素。
它是按照行, 也就是一維數(shù)組處理的。要想訪問二維教組 a 的所有元素, 需要使用兩個(gè)嵌套的循環(huán), 如下所示:
for (double[] row : a) { for (double value : row) { ...... } }
把【例2】修改為使用 for each 循環(huán)語句輸出,代碼如下所示:
public static void main(String[] args) { double[][] class_score = { { 100, 99, 99 }, { 100, 98, 97 }, { 100, 100, 99.5 }, { 99.5, 99, 98.5 } }; for (double[] row : class_score) { for (double value : row) { System.out.println(value); } } }
輸出結(jié)果為:
100.0
99.0
99.0
100.0
98.0
97.0
100.0
100.0
99.5
99.5
99.0
98.5
提示:要想快速地打印一個(gè)二維數(shù)組的數(shù)據(jù)元素列表,可以調(diào)用:
System.out.println(Arrays.deepToString(arrayName));
代碼如下:
System.out.println(Arrays.deepToString(class_score));
輸出格式為:
[[100.0, 99.0, 99.0], [100.0, 98.0, 97.0], [100.0, 100.0, 99.5], [99.5, 99.0, 98.5]]
獲取整行元素
除了獲取單個(gè)元素和全部元素之外,還可以單獨(dú)獲取二維數(shù)組的某一行中所有元素的值,或者二維數(shù)組中某一列元素的值。
獲取指定行的元素時(shí),需要將行數(shù)固定,然后只遍歷該行中的全部列即可。
例 5
編寫一個(gè)案例,接收用戶在控制臺(tái)輸入的行數(shù),然后獲取該行中所有元素的值。代碼如下:
public static void main(String[] args) { double[][] class_score = { { 100, 99, 99 }, { 100, 98, 97 }, { 100, 100, 99.5 }, { 99.5, 99, 98.5 } }; Scanner scan = new Scanner(System.in); System.out.println("當(dāng)前數(shù)組只有" + class_score.length + "行,您想查看第幾行的元素?請輸入:"); int number = scan.nextInt(); for (int j = 0; j < class_score[number - 1].length; j++) { System.out.println("第" + number + "行的第[" + j + "]個(gè)元素的值是:" + class_score[number - 1][j]); } }
執(zhí)行上述代碼進(jìn)行測試,輸出結(jié)果如下所示。
當(dāng)前數(shù)組只有4行,您想查看第幾行的元素?請輸入: 3 第3行的第[0]個(gè)元素的值是:100.0 第3行的第[1]個(gè)元素的值是:100.0 第3行的第[2]個(gè)元素的值是:99.5
獲取整列元素
獲取指定列的元素與獲取指定行的元素相似,保持列不變,遍歷每一行的該列即可。
例 6
編寫一個(gè)案例,接收用戶在控制臺(tái)中輸入的列數(shù),然后獲取二維數(shù)組中所有行中該列的值。代碼如下:
public static void main(String[] args) { double[][] class_score = { { 100, 99, 99 }, { 100, 98, 97 }, { 100, 100, 99.5 }, { 99.5, 99, 98.5 } }; Scanner scan = new Scanner(System.in); System.out.println("您要獲取哪一列的值?請輸入:"); int number = scan.nextInt(); for (int i = 0; i < class_score.length; i++) { System.out.println("第 " + (i + 1) + " 行的第[" + number + "]個(gè)元素的值是" + class_score[i][number]); } }
執(zhí)行上述代碼進(jìn)行測試,如下所示。
您要獲取哪一列的值?請輸入: 2 第 1 行的第[2]個(gè)元素的值是99.0 第 2 行的第[2]個(gè)元素的值是97.0 第 3 行的第[2]個(gè)元素的值是99.5 第 4 行的第[2]個(gè)元素的值是98.5
Java不規(guī)則數(shù)組
通過前面的學(xué)習(xí)我們知道 Java 實(shí)際上沒有多維數(shù)組,只有一維數(shù)組。
多維數(shù)組被解釋為是數(shù)組的數(shù)組,所以因此會(huì)衍生出一種不規(guī)則數(shù)組。
規(guī)則的 4×3 二維數(shù)組有 12 個(gè)元素,而不規(guī)則數(shù)組就不一定了。
如下代碼靜態(tài)初始化了一個(gè)不規(guī)則數(shù)組。
int intArray[][] = {{1,2}, {11}, {21,22,23}, {31,32,33}};
高維數(shù)組(二維以及二維以上的數(shù)組稱為高維數(shù)組)是 4 個(gè)元素,但是低維數(shù)組元素個(gè)數(shù)不同,如圖 1 所示,其中第 1 個(gè)數(shù)組有兩個(gè)元素,第 2 個(gè)數(shù)組有 1 個(gè)元素,第 3 個(gè)數(shù)組有 3 個(gè)元素,第 4 個(gè)數(shù)組有 3 個(gè)元素。這就是不規(guī)則數(shù)組。
圖 1 不規(guī)則數(shù)組
動(dòng)態(tài)初始化不規(guī)則數(shù)組比較麻煩,不能使用 new int[4][3] 語句,而是先初始化高維數(shù)組,然后再分別逐個(gè)初始化低維數(shù)組。代碼如下:
int intArray[][] = new int[4][]; //先初始化高維數(shù)組為4 // 逐一初始化低維數(shù)組 intArray[0] = new int[2]; intArray[1] = new int[1]; intArray[2] = new int[3]; intArray[3] = new int[3];
從上述代碼初始化數(shù)組完成之后,不是有 12 個(gè)元素而是 9 個(gè)元素,它們的下標(biāo)索引如圖 2 所示,可見其中下標(biāo) [0][2]、[1][1] 和 [1][2] 是不存在的,如果試圖訪問它們則會(huì)拋出下標(biāo)越界異常。
圖 2 不規(guī)則數(shù)組訪問
提示:下標(biāo)越界異常(ArrayIndexOutOfBoundsException)是試圖訪問不存在的下標(biāo)時(shí)引發(fā)的。
例如一個(gè)一維 array 數(shù)組如果有 10 個(gè)元素,那么表達(dá)式 array[10] 就會(huì)發(fā)生下標(biāo)越界異常,這是因?yàn)閿?shù)組下標(biāo)是從 0 開始的,最后一個(gè)元素下標(biāo)是數(shù)組長度減 1,所以 array[10] 訪問的元素是不存在的。
下面介紹一個(gè)不規(guī)則數(shù)組的示例:
import java.util.Arrays; public class HelloWorld { public static void main(String[] args) { int intArray[][] = new int[4][]; // 先初始化高維數(shù)組為4 // 逐一初始化低維數(shù)組 intArray[0] = new int[2]; intArray[1] = new int[1]; intArray[2] = new int[3]; intArray[3] = new int[3]; // for循環(huán)遍歷 for (int i = 0; i < intArray.length; i++) { for (int j = 0; j < intArray[i].length; j++) { intArray[i][j] = i + j; } } // for-each循環(huán)遍歷 for (int[] row : intArray) { for (int column : row) { System.out.print(column); // 在元素之間添加制表符, System.out.print('\t'); } // 一行元素打印完成后換行 System.out.println(); } System.out.println(intArray[0][2]); // 發(fā)生運(yùn)行期錯(cuò)誤 } }
不規(guī)則數(shù)組訪問和遍歷可以使用 for 和 for-each 循環(huán),但要注意下標(biāo)越界異常發(fā)生。
上述代碼第 18 行和第 19 行采用 for-each 循環(huán)遍歷不規(guī)則數(shù)組,其中代碼第 18 行 for-each 循環(huán)取出的數(shù)據(jù)是 int 數(shù)組,所以 row 類型是 int[]。代碼第 19 行 for-each 循環(huán)取出的數(shù)據(jù)是 int 數(shù)據(jù),所以 column 的類型 int。
另外,注意代碼第 27 行試圖訪問 intArray[0][2]元素,由于 [0][2] 不存在所以會(huì)發(fā)生下標(biāo)越界異常。
Java數(shù)組也是一種數(shù)據(jù)類型
Java 的數(shù)組要求所有的數(shù)組元素具有相同的數(shù)據(jù)類型。
因此,在一個(gè)數(shù)組中,數(shù)組元素的類型是唯一的,即一個(gè)數(shù)組里只能存儲(chǔ)一種數(shù)據(jù)類型的數(shù)據(jù),而不能存儲(chǔ)多種數(shù)據(jù)類型的數(shù)據(jù)。
因?yàn)?Java 語言是面向?qū)ο蟮恼Z言,而類與類之間可以支持繼承關(guān)系(從已有的類中派生出新的類,新的類能吸收已有類的數(shù)據(jù)屬性和行為),這樣可能產(chǎn)生一個(gè)數(shù)組里可以存放多種數(shù)據(jù)類型的假象。
例如有一個(gè)水果數(shù)組,要求每個(gè)數(shù)組元素都是水果,實(shí)際上數(shù)組元素既可以是蘋果,也可以是香蕉(蘋果、香蕉都繼承了水果,都是一種特殊的水果),但這個(gè)數(shù)組的數(shù)組元素的類型還是唯一的,只能是水果類型。
一旦數(shù)組的初始化完成,數(shù)組在內(nèi)存中所占的空間將被固定下來,因此數(shù)組的長度將不可改變。
即使把某個(gè)數(shù)組元素的數(shù)據(jù)清空,但它所占的空間依然被保留,依然屬于該數(shù)組,數(shù)組的長度依然不變。
Java 的數(shù)組既可以存儲(chǔ)基本類型的數(shù)據(jù),也可以存儲(chǔ)引用類型的數(shù)據(jù),只要所有的數(shù)組元素具有相同的類型即可。
值得指出的是,數(shù)組也是一種數(shù)據(jù)類型,它本身是一種引用類型。
例如 int 是一個(gè)基本類型,但 int[](這是定義數(shù)組的一種方式)就是一種引用類型了。
int[] 是一種類型嗎?怎么使用這種類型呢?
沒錯(cuò),int[] 就是一種數(shù)據(jù)類型,與 int 類型、String 類型相似,一樣可以使用該類型來定義變量,也可以使用該類型進(jìn)行類型轉(zhuǎn)換等。
使用 int[] 類型來定義變量、進(jìn)行類型轉(zhuǎn)換時(shí)與使用其他普通類型沒有任何區(qū)別。
int[] 類型是一種引用類型,創(chuàng)建 int[] 類型的對象也就是創(chuàng)建數(shù)組,需要使用創(chuàng)建數(shù)組的語法。
Java中到底有沒有多維數(shù)組(長篇神文)?
Java 中沒有多維數(shù)組的概念,從數(shù)組底層的運(yùn)行機(jī)制上來看 Java 沒有多維數(shù)組,但是 Java 提供了支持多維數(shù)組的語法,可以實(shí)現(xiàn)多維數(shù)組的功能。
Java 語言里的數(shù)組類型是引用類型,因此數(shù)組變量其實(shí)是一個(gè)引用,這個(gè)引用指向真實(shí)的數(shù)組內(nèi)存。數(shù)組元素的類型也可以是引用,如果數(shù)組元素的引用再次指向真實(shí)的數(shù)組內(nèi)存,這種情形看上去很像多維數(shù)組。
定義數(shù)組類型的語法
type[] arrName;
是典型的一維數(shù)組的定義語法,其中 type 是數(shù)組元素的類型。
如果希望數(shù)組元素也是一個(gè)引用,而且是指向 int 數(shù)組的引用,則可以把 type 具體成 int[](前面已經(jīng)指出,int[] 就是一種類型,int[] 類型的用法與普通類型并無任何區(qū)別),那么上面定義數(shù)組的語法就是
int[][] arrName
如果把 int 這個(gè)類型擴(kuò)大到 Java 的所有類型(不包括數(shù)組類型),則出現(xiàn)了定義二維數(shù)組的語法:
type[][] arrName;
Java 語言采用上面的語法格式來定義二維數(shù)組,但它的實(shí)質(zhì)還是一維數(shù)組,只是其數(shù)組元素也是引用,數(shù)組元素里保存的引用指向一維數(shù)組。
接著對這個(gè)“二維數(shù)組”執(zhí)行初始化,同樣可以把這個(gè)數(shù)組當(dāng)成一維數(shù)組來初始化,把這個(gè)“二維數(shù)組”當(dāng)成一個(gè)一維數(shù)組,其元素的類型是 type[] 類型,則可以采用如下語法進(jìn)行初始化:
arrName = new type[length][]
上面的初始化語法相當(dāng)于初始化了一個(gè)一維數(shù)組,這一維數(shù)組的長度是 length。
同樣,因?yàn)檫@個(gè)一維數(shù)組的數(shù)組元素是引用類型(數(shù)組類型)的,所以系統(tǒng)為每個(gè)數(shù)組元素都分配初始值:null。
這個(gè)二維數(shù)組實(shí)際上完全可以當(dāng)成一維數(shù)組使用:使用
new type[length]
初始化一維數(shù)組后,相當(dāng)于定義了 length 個(gè) type 類型的變量。
類似的,使用
new type[length][]
初始化這個(gè)數(shù)組后,相當(dāng)于定義了 length 個(gè) type[] 類型的變量。
當(dāng)然,這些 type[] 類型的變量都是數(shù)組類型,因此必須再次初始化這些數(shù)組。
下面程序示范了如何把二維數(shù)組當(dāng)成一維數(shù)組處理。
public class TwoDimensionTest { public static void main(String[] args) { // 定義一個(gè)二維數(shù)組 int[][] a; // 把a(bǔ)當(dāng)成一維數(shù)組進(jìn)行初始化,初始化a是一個(gè)長度為4的數(shù)組 // a數(shù)組的數(shù)組元素又是引用類型 a = new int[4][]; // 把a(bǔ)數(shù)組當(dāng)成一維數(shù)組,遍歷a數(shù)組的每個(gè)數(shù)組元素 for (int i = 0, len = a.length; i < len; i++) { System.out.println(a[i]); // 輸出 null null null null } // 初始化a數(shù)組的第一個(gè)元素 a[0] = new int[2]; // 訪問a數(shù)組的第一個(gè)元素所指數(shù)組的第二個(gè)元素 a[0][1] = 6; // a數(shù)組的第一個(gè)元素是一個(gè)一維數(shù)組,遍歷這個(gè)一維數(shù)組 for (int i = 0, len = a[0].length; i < len; i++) { System.out.println(a[0][i]); // 輸出 0 6 } } }
上面程序中粗體字代碼部分把 a 這個(gè)二維數(shù)組當(dāng)成一維數(shù)組處理,只是每個(gè)數(shù)組元素都是 null,所以看到輸出結(jié)果都是 null。
下面結(jié)合示意圖來說明這個(gè)程序的執(zhí)行過程。
程序中代碼
int[][] a;
將在棧內(nèi)存中定義一個(gè)引用變量,這個(gè)變量并未指向任何有效的內(nèi)存空間,此時(shí)的堆內(nèi)存中還未為這行代碼分配任何存儲(chǔ)區(qū)。
程序中代碼
a = new int[4][];
對a 數(shù)組執(zhí)行初始化,這行代碼讓 a 變量指向一塊長度為 4 的數(shù)組內(nèi)存,這個(gè)長度為 4 的數(shù)組里每個(gè)數(shù)組元素都是引用類型(數(shù)組類型),系統(tǒng)為這些數(shù)組元素分配默認(rèn)的初始值:null。此時(shí) a 數(shù)組在內(nèi)存中的存儲(chǔ)示意圖如圖 1 所示。
圖 1 將二維數(shù)組當(dāng)成一維數(shù)組初始化的存儲(chǔ)示意圖
從圖 1 來看,雖然聲明 a 是一個(gè)二維數(shù)組,但這里絲毫看不出它是一個(gè)二維數(shù)組的樣子,完全是一維數(shù)組的樣子。
這個(gè)一維數(shù)組的長度是 4,只是這 4 個(gè)數(shù)組元素都是引用類型,它們的默認(rèn)值是 null。
所以程序中可以把 a 數(shù)組當(dāng)成一維數(shù)組處理,依次遍歷 a 數(shù)組的每個(gè)元素,將看到每個(gè)數(shù)組元素的值都是 null。
由于 a 數(shù)組的元素必須是 int[] 數(shù)組,所以接下來的程序?qū)?a[0] 元素執(zhí)行初始化,也就是讓圖 1 右邊堆內(nèi)存中的第一個(gè)數(shù)組元素指向一個(gè)有效的數(shù)組內(nèi)存,指向一個(gè)長度為 2 的 int 數(shù)組。
因?yàn)槌绦虿捎脛?dòng)態(tài)初始化 a[0] 數(shù)組,因此系統(tǒng)將為 a[0] 所引用數(shù)組的每個(gè)元素分配默認(rèn)的初始值:0,然后程序顯式為 a[0] 數(shù)組的第二個(gè)元素賦值為 6。
此時(shí)在內(nèi)存中的存儲(chǔ)示意圖如圖 2 所示。
圖 2 初始化a[0]后的存儲(chǔ)示意圖
圖 2 中灰色覆蓋的數(shù)組元素就是程序顯式指定的數(shù)組元素值。
TwoDimensionTest.java 接著迭代輸出 a[0] 數(shù)組的每個(gè)數(shù)組元素,將看到輸出 0 和 6。
是否可以讓圖 2 中灰色覆蓋的數(shù)組元素再次指向另一個(gè)數(shù)組?這樣不就可以擴(kuò)展成三維數(shù)組,甚至擴(kuò)展成更多維的數(shù)組嘛?
不能!至少在這個(gè)程序中不能。
因?yàn)?Java 是強(qiáng)類型語言,當(dāng)定義 a 數(shù)組時(shí),已經(jīng)確定了 a 數(shù)組的數(shù)組元素是 int[] 類型,則 a[0] 數(shù)組的數(shù)組元素只能是 int 類型,所以灰色覆蓋的數(shù)組元素只能存儲(chǔ) int 類型的變量。
對于其他弱類型語言,例如 JavaScript 和 Ruby 等,確實(shí)可以把一維數(shù)組無限擴(kuò)展,擴(kuò)展成二維數(shù)組、三維數(shù)組…,如果想在 Java 語言中實(shí)現(xiàn)這種可無限擴(kuò)展的數(shù)組,則可以定義一個(gè) Object[] 類型的數(shù)組,這個(gè)數(shù)組的元素是 Object 類型,因此可以再次指向一個(gè) Object[] 類型的數(shù)組,這樣就可以從一維數(shù)組擴(kuò)展到二維數(shù)組、三維數(shù)組…
從上面程序中可以看出,初始化多維數(shù)組時(shí),可以只指定最左邊維的大??;當(dāng)然,也可以一次指定每一維的大小。例如下面代碼:
// 同時(shí)初始化二維數(shù)組的兩個(gè)維數(shù) int[][] b = new int[3][4];
上面代碼將定義一個(gè) b 數(shù)組變量,這個(gè)數(shù)組變量指向一個(gè)長度為 3 的數(shù)組,這個(gè)數(shù)組的每個(gè)數(shù)組元素又是一個(gè)數(shù)組類型,它們各指向?qū)?yīng)的長度為 4 的 int[] 數(shù)組,每個(gè)數(shù)組元素的值為 0。
這行代碼執(zhí)行后在內(nèi)存中的存儲(chǔ)示意圖如圖 3 所示。
圖 3 同時(shí)初始化二維數(shù)組的兩個(gè)維數(shù)后的存儲(chǔ)示意圖
還可以使用靜態(tài)初始化方式來初始化二維數(shù)組。
使用靜態(tài)初始化方式來初始化二維數(shù)組時(shí),二維數(shù)組的每個(gè)數(shù)組元素都是一維數(shù)組,因此必須指定多個(gè)一維數(shù)組作為二維數(shù)組的初始化值。如下代碼所示:
// 使用靜態(tài)初始化語法來初始化一個(gè)二維數(shù)組 String[][] str1 = new String[][]{new String[3], new String[]{“hello”}}; // 使用簡化的靜態(tài)初始化語法來初始化二維數(shù)組 String[][] str2 = {new String[3], new String [] {“hello”}};
上面代碼執(zhí)行后內(nèi)存中的存儲(chǔ)示意圖如圖 4 所示。
圖 4 采用靜態(tài)初始化語法初始化二維數(shù)組的存儲(chǔ)示意圖
通過上面講解可以得到一個(gè)結(jié)論:二維數(shù)組是一維數(shù)組,其數(shù)組元素是一維數(shù)組。三維數(shù)組也是一維數(shù)組,其數(shù)組元素是二維數(shù)組…… 從這個(gè)角度來看,Java 語言里沒有多維數(shù)組。
到此這篇關(guān)于Java數(shù)組(Array)最全匯總(中篇)的文章就介紹到這了,其他兩個(gè)部分的內(nèi)容(上、下篇)請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java數(shù)組(Array)最全匯總(上篇)
- Java之?dāng)?shù)組在指定位置插入元素實(shí)現(xiàn)
- Java自定義一個(gè)變長數(shù)組的思路與代碼
- Java中如何將?int[]?數(shù)組轉(zhuǎn)換為?ArrayList(list)
- Java中將 int[] 數(shù)組 轉(zhuǎn)換為 List分享
- java如何將int數(shù)組轉(zhuǎn)化為Integer數(shù)組
- 淺談Java當(dāng)作數(shù)組的幾個(gè)應(yīng)用場景
- 計(jì)算Java數(shù)組長度函數(shù)的方法以及代碼分析
- Java C++題解leetcode915分割數(shù)組示例
- Java?從json提取數(shù)組并轉(zhuǎn)換為list的操作方法
- Java數(shù)據(jù)結(jié)構(gòu)之稀疏數(shù)組的實(shí)現(xiàn)與應(yīng)用
- Java?C++題解leetcode1441用棧操作構(gòu)建數(shù)組示例
- Java postgresql數(shù)組字段類型處理方法詳解
- Java中數(shù)組的常見操作合集
- 關(guān)于Java?SE數(shù)組的深入理解
- Java二維數(shù)組與稀疏數(shù)組相互轉(zhuǎn)換實(shí)現(xiàn)詳解
- Java數(shù)組隊(duì)列及環(huán)形數(shù)組隊(duì)列超詳細(xì)講解
- Java數(shù)組(Array)最全匯總(下篇)
相關(guān)文章
基于Log4j2阻塞業(yè)務(wù)線程引發(fā)的思考
這篇文章主要介紹了基于Log4j2阻塞業(yè)務(wù)線程引發(fā)的思考,基于很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12Java實(shí)現(xiàn)軟件運(yùn)行時(shí)啟動(dòng)信息窗口的方法
這篇文章主要介紹了Java實(shí)現(xiàn)軟件運(yùn)行時(shí)啟動(dòng)信息窗口的方法,比較實(shí)用的功能,需要的朋友可以參考下2014-08-08Java之next()、nextLine()區(qū)別及問題解決
這篇文章主要介紹了Java之next()、nextLine()區(qū)別及問題解決,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08基于eclipse-temurin鏡像部署spring boot應(yīng)用的實(shí)現(xiàn)示例
本文提供了基于eclipse-temurin鏡像部署Spring Boot應(yīng)用的詳細(xì)實(shí)現(xiàn)示例,通過使用Docker鏡像,可以輕松地創(chuàng)建和管理Spring Boot應(yīng)用程序的容器化環(huán)境,感興趣的可以了解一下2023-08-08springboot啟動(dòng)掃描不到dao層接口的解決方案
這篇文章主要介紹了springboot啟動(dòng)掃描不到dao層接口的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Spring Boot整合Web項(xiàng)目常用功能詳解
這篇文章主要介紹了Spring Boot整合Web項(xiàng)目常用功能詳解,在Web應(yīng)用開發(fā)過程中,可以通過Spring Boot的Starter來將這些常用功能進(jìn)行整合與集中維護(hù),以達(dá)到開箱即用的目的。,需要的朋友可以參考下2019-06-06Springboot通過lucene實(shí)現(xiàn)全文檢索詳解流程
Lucene是一個(gè)基于Java的全文信息檢索工具包,它不是一個(gè)完整的搜索應(yīng)用程序,而是為你的應(yīng)用程序提供索引和搜索功能。Lucene 目前是 Apache Jakarta 家族中的一個(gè)開源項(xiàng)目,也是目前最為流行的基于 Java 開源全文檢索工具包2022-06-06