2014-12-05 6 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', но как насчет копий' 'List объектов? Помните, что Java передается по значению, а значение - это ссылка на объекты. –

+0

Не было бы проще заменить списки значений в копии новыми списками и добавить первый элемент соответствующего списка из оригинала? – adamdc78

+0

Кроме того, очистка может быть выполнена более эффективно как 'value.subList (1, value.size()). Clear()'. –

ответ

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 хорошей Job :). Благодаря! – TheKolaNN

Смежные вопросы