2014-12-05 43 views
0

我想創建鏈接哈希映射的副本,然後我想要從列表中刪除所有值(而不是第一個條目)。這是我得到的:Java:LinkedHashMaps自身重疊

LinkedHashMap<String, List<Value>> facetsInCategoriesCopy = new LinkedHashMap<>(facetsInCategories); 

if (!facets.equals("something")) { 
    for (List<Value> value : facetsInCategoriesCopy.values()) { 
     if (value.size() > 1) { 
      int nbrOfElements = value.size(); 
      for (int i = nbrOfElements-1; i > 0; i--) { 
       value.remove(i); 
      } 
     } 
    } 
} 

在這個操作後,事實證明facetsInCategories也被修改了。爲什麼?以及如何解決這個問題? 任何幫助,將不勝感激。

+3

您可能已創建的副本'LinkedHashMap',但什麼'名單'對象的副本?請記住,Java是按值傳遞的,值是對對象的引用。 – 2014-12-05 20:41:12

+0

使用新列表替換副本中的值列表並添加原始對應列表的第一個元素會不會更容易? – adamdc78 2014-12-05 21:00:06

+0

此外,可以通過'value.subList(1,value.size())。clear()'更有效地完成清除操作。 – 2014-12-05 21:23:52

回答

1

我沒有50的評論添加評論。看到這個答案Assigning Hashmap to Hashmap

本質上講,你用來做新的地圖具有的可變對象的引用,即facetsInCategories和將更新以及在更新facetsInCategoriesCopy地圖拷貝構造函數。

解決方法是改爲執行深層複製。我在下面添加測試代碼,我用String代替Value

//Test for https://stackoverflow.com/questions/27324315/ 
    public static void testStackO_Q_27324315() { 

    Map<String, List<String>> facetsInCategories = new LinkedHashMap<String, List<String>>(); 
    String[] values = new String[]{"Test1", "Test2", "Test3"}; 
    List<String> valuesList = new ArrayList<String>(Arrays.asList(values)); 
    facetsInCategories.put("Test", valuesList); 

    Map temp = Collections.unmodifiableMap(facetsInCategories); 
    LinkedHashMap<String, List<String>> facetsInCategoriesCopy = (LinkedHashMap<String, List<String>>)deepCopy(temp); 

    String facets = "test_me"; 

    if (!facets.equals("something")) { 
     for (List<String> value : facetsInCategoriesCopy.values()) { 
      if (value.size() > 1) { 
       int nbrOfElements = value.size(); 
       for (int i = nbrOfElements-1; i > 0; i--) { 
        value.remove(i); 
       } 
      } 
     } 
    } 

    System.out.println(facetsInCategories); 
    System.out.println(facetsInCategoriesCopy); 
} 

public static <K1, K2, V> Map<K1, List<V>> deepCopy(
     Map<K1, List<V>> original){ 

     Map<K1, List<V>> copy = new LinkedHashMap<K1, List<V>>(); 
     for(Map.Entry<K1, List<V>> entry : original.entrySet()){ 
      copy.put(entry.getKey(), new ArrayList<V>(entry.getValue())); 
     } 
     return copy; 
    } 
+0

嗨,你的deepCopy功能使得Preety很好的工作:)。謝謝! – TheKolaNN 2014-12-08 09:27:28