2013-07-16 43 views
1

問:爲什麼以下打印出來:從Java util列表讀取時,爲什麼所有元素都返回最後一個元素? (廣義)

ChildB___Parent of ChildB 
ChildB___Parent of ChildB 

相反的是什麼,我認爲它應該打印出來:

ChildA___Parent of ChildA 
ChildB___Parent of ChildB 

短期自住問題的廣義示例:

import java.util.ArrayList; 
import java.util.List; 

public class StackExchangeQuestion1 { 
public static void main(String[] args){ 
    List<String[]> list = new ArrayList(); 
    String[] pair = {"childID","parentID"}; //for readability this gets overwritten  

//adding values to list 
    pair[0] = "ChildA"; 
    pair[1] = "Parent of ChildA"; 
    list.add(pair); 

    pair[0] = "ChildB"; 
    pair[1] = "Parent of ChildB"; 
    list.add(pair); 

//checking values in list 
    for(int i=0;i<list.size();i++){ 
    pair = list.get(i); //variable reuse for readability 
    System.out.println(pair[0]+"___"+pair[1]); 
    } 
}}//end class and main 
+0

注意:我搜索了以前的答案,這是至少2的副本http://stackoverflow.com/questions/10509335/referencing-a-java-list-always-returns-the-last-element http ://stackoverflow.com/questions/4324754/why-all-elements-of-my-list-seems-to-be-the-same --- 我提出了一個新的問題,因爲那些不是短自包含的通用問題/問題的例子,而且不是讀者友好的。 (代碼做了10件事,但問題只涉及1件事)我也不想用我自己的方式劫持他們的問題。 – neokyle

+0

我試過用循環內容替換:System.out.println(list。得到(ⅰ)[0] + 「___」 + list.get(I)[1]);我也嘗試過使用arraylist,都沒有工作。 – neokyle

回答

4

您正在向清單添加兩次相同的String[]參考。因此,列表中的兩個元素都指向同一個對象。所以,當你重寫你的數組時,你確實在寫同一塊內存。該列表是兩次引用這段內存,所以你得到2個相同的打印語句。

Java將通過引用傳遞所有非原始值(這意味着它會通過一個指針到一個非原始對象被存儲在存儲器中。)

如果你存儲整數代替像這樣:

int a = 10; 
list.add(a); 
a = 20; 
list.add(a); 

一切都會好起來的,因爲a是一個整數,整數是原始值,原始值按值通過這意味着數據被存儲在一個被複制到列表中,而不是在內存中的點a被保存在。

但是,任何類型的字符串和數組都是非原始的。

要解決你的代碼,你需要通過2個獨立的引用到您的列表:

String[] pair1 = {"ChildA","Parent of ChildA"}; 
String[] pare2 = {"ChildB", "Parent of ChildB"}; 
//adding values to list 
list.add(pair1); 
list.add(pair2); 

編輯:在約冗長的評論

你會表示關切。首先,我認爲你的代碼不是冗長的。但如果你真的關心它,這裏有一個縮短它的方法:

list.add(new String[]{"ChildA","Parent of ChildA"}); 
list.add(new String[]{"ChildB","Parent of ChildB"}); 
+0

謝謝你的徹底解答,我想我錯過了一些根本。 – neokyle

+0

我如何讓java按值傳遞非原始值?所以我可以減少冗長的代碼。 ----或者這只是錯誤的,我應該使用一種方法來創建一個新的ArrayList對象,該對象具有我想要的值,以減少冗長的代碼。 – neokyle

+0

這並沒有錯 - 它是我在工作中有時使用的一種方法。你必須執行所謂的淺拷貝。您創建一個新的參考,並用舊參考中的數據填充它。在這種情況下,您需要創建一個新數組,並將其填入前一個內容。但是,這會使你的代碼更加冗長,而不是更少。然而,我不覺得你的代碼在這裏是冗長的。詳細代碼聲明過多的臨時變量或過多的評論恕我直言。你既沒有做。我認爲你很好。 –

2

因爲ArrayList存儲引用nces,而不是對象。參考文獻pair總是指同一個對象;您只需將該引用添加到列表中兩次。

0

你的字符串對象數組在這裏覆蓋。您的最後更改只會反映在您的字符串中,因爲列表將存儲對象的引用。如果你想讓你的假設輸出在每次設置值之前創建新對象。

相關問題