2014-10-02 58 views
2

隨着下面的Java例子:Java多維數組 - 爲什麼只定義足夠的第一個大小?

int[] array1 = new int[]; // Incorrect, since no size is given 
int[] array2 = new int[2]; // Correct 
int[][][] array3 = new int[][][]; // Incorrect, since no size is given 
int[][][] array4 = new int[2][2][2]; // Correct 
int[][][] array5 = new int[2][][]; // Correct (why is this correct?) 

所以,我的問題是,爲什麼只分配一個多維數組足以第一大小?我想你總是要指定一個尺寸,甚至多維數組的每一個人陣列的一部分,但今天我發現array5也是一個Java的正確途徑。現在我只是想知道爲什麼。有人可以舉例說明爲什麼這適用於多維數組和/或其背後的推理嗎?

而且,我想,下面也適用,那麼:

int[][][] array6 = new int[][2][]; // Incorrect 
int[][][] array7 = new int[][][2]; // Incorrect 
int[][][] array8 = new int[][2][2]; // Incorrect 
int[][][] array9 = new int[2][2][]; // Correct 
int[][][] array10 = new int[2][][2]; // Incorrect?? (Or is this correct?) 

我現在有點納悶,想澄清,如果有人知道它。


編輯/ SEMI-SOLUTION:

好吧,我找到了原因,第一部分作品:

int[][] array = new int[2][]; 
array[0] = new int[5]; 
array[1] = new int[3]; 
// So now I have an array with the following options within the array-index bounds: 
// [0][0]; [0][1]; [0][2]; [0][3]; [0][4]; [1][0]; [1][1]; [1][2] 
// It basically means I can have different sized inner arrays 

唯一剩下回答是,如果:

int[][][] array10 = new int[2][][2]; // Incorrect?? (Or is this correct?) 

是否有效。

回答

3

開始簡單:一個2維數組是數組的數組。 Java中的數組是對象。只有定義第一個大小才能創建一個給定大小的數組,但可能會存儲其他數組,但這些數據仍然爲空。所以在使用它之前,你需要調用類似array1[0] = new int[5]的東西,否則你會得到一個NullPointerException。對於更多維數組,這適用於此。

從理論上講,實際上,所有「內部」數組的長度可能不同。所以你可以寫一些如:array1[0] = new int[1]; array1[1] = new int[4];

關於你的最後一個問題: 這是無效的,Java編譯器會說「不能在空維之後指定數組維數」。這是由於未指定第二個級別,因此在第一級數組中是空對象,因此,在這些空數組上不能指定維度。

1

因爲你沒有定義一個多維數組。你實際上定義的是一組數組ints的數組。例如,你可以做這樣的事情:

int[][] array1 = new int[5][]; 
for(int i = 0; i < 5; i++){ 
    array1[i] = new int[i]; 
} 

這導致鋸齒陣列。

所以int[2][]限定陣列的陣列。 int[2][2]定義了一個數組數組,並且還定義了所有的內部數組。 int[][2]嘗試定義所有內部數組,但沒有任何內容,因此失敗。

另一種方式去思考的,這是你以後可以改變存儲的最外層數組中引用(即更改值的行),但你不能沿另一個軸修改(修改一列)。因此,這是有效的:

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

雖然這不是:

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

這是因爲

int[][][] array = new int[n][m][p]; 

相當於創建了多維數組,然後用引用加油吧到m維數組的實例,然後使用對p維數組的m個實例的引用填充該數組。

當不是所有的尺寸都存在,則有部分初始化數組。

0
int[][][] array5 = new int[2][][]; // Correct (why is this correct) 

寫這個你instanciate int [] []的數組。在內存中,它是對int [] []的引用數組。你不需要知道int [] []的大小,因爲它只是一個引用,每個大小可能不同。

看到內存是這樣的:

array5:[length a ref, length of a ref] 

然後你實例化的subArray0:

... ,subArray0[ length of a ref, length of a ref], ... 

,影響子陣列主陣列

array5:[refToSubArray0, length of a ref], 

但不管第一個子數組的長度,你只需要在內存中保存一個引用的長度來存儲你自己的子數組存儲在其他地方。

int[][][] array10 = new int[2][][2]; // Correct?? (Is this correct?) 

這是不正確的。我beleive,當你做

new int[2][2][2] 

你在內存分配:

array[ref0,ref1], sub0[ref00,ref01], sub1[ref10,ref11], sub00[int000, int001], sub00[int000, int001], sub01[int010, int011], sub10[int100, int101], sub11[int110, int111] ... 

如果你跳過一個數組的大小,它不能爲第三子陣列,因爲它不知道有多少分配內存子陣列將被立即執行。

相關問題