2014-04-07 36 views
0

我有一個返回1D數組的方法。我想在一個循環中調用該方法並將結果存儲在二維數組中。當使用foreach循環時它不起作用,數組結果充滿了空指針。爲什麼我不能使用foreach循環將一維數組分配給二維數組?

//this doesn't work 
... 
double[][] results = new double[20][]; 
for(double[] result : results){ 
     result = method(); 
} 
... 
public double[] method(){ 
     double[] ret = new double[15]; 
     //populate ret and do other stuff... 
     return ret; 
} 

但是,當使用常規「for」循環迭代數組時,它會奇蹟般地工作!

... 
double[][] results = new double[20][]; 
for(int i=0;i<20;i++){ 
     results[i]=method(); 
} 
... 
public double[] method(){ 
     double[] ret = new double[15]; 
     //populate ret and do other stuff... 
     return ret; 
} 

爲什麼?

回答

4

因爲在增強的for循環中,您可以訪問分配給變量的數組的每個對象引用的副本,並且您正在修改此變量的值,而不是其內容。

for (double[] result : results) { 
    //here result is just a copy of results[0], results[1] and on... 
    //if you modify value of result i.e. assigning a new value 
    //you're just changing the value of the current variable 
    //note that if you modify an object inside the variable is reflected 
    //since you're updating the state of the reference, which is valid 
} 

此代碼可以稍微翻譯成:

for (int i = 0; i < results.length; i++) { 
    double[] result = results[i]; 
    //this explains why the enhanced for doesn't work 
    result = method(); 
} 
+0

那麼可以肯定地說,使用foreach循環創建額外的開銷通過創建每個元素的引用副本? – Leprechaun

+1

@Leprechaun我不會說4或8 KB或更少的內存是額外的開銷...更多信息:[在java中的引用類型大小](http://stackoverflow.com/q/5350950/1065197) –

2

因爲,在循環,result是存儲在數組中的基準的一個副本。並且你爲這個副本分配一個新的數組。因此,最初的參考是左不變:

分配

results[i] ----> null 
       ^
result -----------| 

任務後前:

results[i] ----> null 

result --------> double array 
0

,因爲你不使用索引時,它不會在第一個例子中工作您將一維數組分配給您的二維數組:

result = method(); 

這裏的結果只是一個局部變量,其範圍是foreach循環,因此您只將數組賦予此局部變量。 2D陣列保持不變。

您可以使用帶手動索引的foreach進行管理,在進入循環並手動遞增之前將其設置爲0。但在這種情況下,經典for循環可能更適合。