2014-05-05 78 views
1

看看這個小例子現在哈希表和ArrayList

import java.util.ArrayList; 
import java.util.HashMap; 

public class Foo { 
public static void main(String[] args) { 

    ArrayList<Integer> array = new ArrayList<Integer>(); 
    HashMap<String, ArrayList<Integer>> foo = new HashMap<String,ArrayList<Integer>>(); 

    for (int i = 0; i < 20; i++) 
     array.add(i); 

    foo.put("1", array); 
    // array.clear(); 

    System.out.println(foo.get("1").size()); 
} 
} 

,如果使用array.clear()它會自動刪除與HashMap的內指定鍵關聯ArrayList中的所有值

如何我能阻止這個嗎?

  • 我可以(在HashMap中輸入值之後)執行array.clear();和僅刪除的ArrayList<Integer> array

  • 的值的值,的:

    在使得方式

    陣列與該密鑰關聯,不會被刪除裏面的哈希映射

如果你啓動這個程序,它會打印沒有使用array.clear();,代替

+0

你確定你明白java在各處使用對象的引用嗎?如果在HashMap中存儲對數組的引用,那麼它與本地變量引用的對象是同一個對象。 – Andrey

+0

在你的hashmap聲明中,你提供了對同一個對象的引用,所以很明顯它會從兩個地方被刪除(顯然它不存在於兩個地方只有一個數組存在),你可以在兩個地方使用一個數組。正如@Andrey所說的,請通過java如何使用對象引用來更好地理解它。 – Setu

+0

CiMat,看到我的答案.. – niiraj874u

回答

2

它刪除地圖鍵元素,因爲兩者都是相同的對象。你必須讓一個淺拷貝,使這兩個列表分開

創建淺拷貝是很容易做的:

List<Integer> newList = new ArrayList<Integer>(oldList); 

下面是代碼:

public class Foo { 
    public static void main(String[] args) { 

     ArrayList<Integer> array = new ArrayList<Integer>(); 
     HashMap<String, ArrayList<Integer>> foo = new HashMap<String, ArrayList<Integer>>(); 

     for (int i = 0; i < 20; i++) 
      array.add(i); 

     ArrayList<Integer> newList = new ArrayList<Integer>(array); 

     foo.put("1", newList); 
     array.clear(); 

     System.out.println(foo.get("1").size()); 
    } 

} 
+0

唯一的辦法就是克隆這些元素?有沒有比這更好的方式? – OiRc

+0

沒有這是做到這一點的唯一方法..要麼複製arraylist – niiraj874u

+1

其實他需要淺層克隆。深度克隆意味着複製陣列中的對象。 – Andrey

2

foo.get("1")array參考同一個對象。你需要foo.put("1", new ArrayList<Integer>(array));

1

只要把不是ArrayList的本身,而是它的副本:

foo.put("1", new ArrayList<Integer>(array)); 

如果你想要把數組本身,你必須有它不可修改:

Map<String, List<Integer>> foo = ...; 
... 
List<Integer> unmodifiableArray = Collections.unmodifiableList(array); 
foo.put(unmodifiableArray); 
1

的問題是,你做不要將「新」對象寫入該地圖。換句話說, 您的列表名爲「數組」,它與地圖中的列表完全相同,所以...如果您更改1,那麼兩個地方都會顯示更改。