2015-01-15 3 views
1

У меня есть List<String> в HashMap как стоимость. Ключ String. Когда я прохожу через HashMap и удаляю элементы из списка определенного ключа, он обновляет списки, сопоставленные всем ключам на карте.Извлечение предмета из списка внутри hashmap

Код ниже

public class ListClass { 
public static void main(String[] args) { 
    ListClass lc = new ListClass(); 
    for(Map.Entry<String, List<String>> entry : lc.postProcessList().entrySet()) { 
     System.out.println("Date : "+entry.getKey()); 
     List<String> data = entry.getValue(); 
     for (int i = 0; i < data.size(); i++) { 
      System.out.println(" Value : "+data.get(i)); 
     } 
    } 
} 

private Map<String,List<String>> postProcessList() { 
    Map<String,List<String>> map = new HashMap<String, List<String>>(); 
    populateMap(map); 
    for(Map.Entry<String, List<String>> entry : map.entrySet()) { 
     String dateKey = entry.getKey(); 
     System.out.println("Date key : "+dateKey); 
     List<String> data = entry.getValue(); 
     System.out.println("List before modification : "+data); 
     for (int i = 0; i < data.size(); i++) { 
      String dateNoTime = data.get(i).split(" ")[0]; 
      if(!dateNoTime.equalsIgnoreCase(dateKey)) { 
       System.out.println("Removing : "+data.get(i)); 
       data.remove(i); 
      } 
     } 
     System.out.println("List after modification: "+data+"\n\n"); 
    } 
    return map; 
} 

private Map<String,List<String>> populateMap(Map<String,List<String>> map) { 
    List<String> list = new ArrayList<String>(); 
    list.add("2015-01-13 09:30:00"); 
    list.add("2015-01-12 05:45:10"); 
    list.add("2015-01-13 06:22:12"); 
    list.add("2015-01-12 01:52:40"); 
    list.add("2015-01-12 02:23:45");  
    map.put("2015-01-12", list); 
    map.put("2015-01-13", list); 
    return map; 
} 
} 

В приведенном выше коде, карта имеет ключ, который является строкой, и хранит значения даты. Список, который является значением карты, содержит дату и время.

Первый ключ - «2015-01-12», и я пытаюсь удалить элементы в списке, которые не являются «2015-01-12». Теперь список в обоих ключах будет обновлен. Почему это так?

ответ

1

Вы вводите тот же список экземпляр на карту против обоих ключей. Поэтому, когда вы извлекаете его с помощью ключа «2015-01-12» и редактируете его, вы увидите изменения на всей карте.

Вам нужно клонировать список, используя что-то вроде list.clone() или new ArrayList<String>(list), прежде чем добавлять его к каждому ключу.

например.

ArrayList<String> list = new ArrayList<String>(); 
list.add("2015-01-13 09:30:00"); 
list.add("2015-01-12 05:45:10"); 
list.add("2015-01-13 06:22:12"); 
list.add("2015-01-12 01:52:40"); 
list.add("2015-01-12 02:23:45");  

map.put("2015-01-12", (List<String>)list.clone()); 
map.put("2015-01-13", (List<String>)list.clone()); 
+0

'clone()' считается сломанным: http://www.artima.com/intv/bloch13.html. Лучше использовать конструктор копирования. – Pshemo

+2

@Pshemo 'clone()' работает в этой ситуации, в частности, поскольку он не требует какого-либо глубокого клонирования. Я согласен с тем, что «клонирование» в качестве концепции противоречиво, да. Альтернативой здесь будет «новый ArrayList (list)», но «clone» семантически сильнее: он идеально подходит для этого использования. –

+0

@ AndyBrown: Отлично. Я изменил код, как вы упомянули, и он работает. Но я до сих пор не понимаю, зачем это нужно? Не будет ли создавать новую ссылку для каждой клавиши, когда я добавлю к ней значение? –