2016-02-03 2 views
-1

У меня есть hashmap из благородных победителей с 1993 по 2009 год, ключевым является год, а значение представляет собой массив строк имен победителей. В течение нескольких лет у вас более одного победителя, а год больше, чем 3. Я пытаюсь удалить конкретное имя из хэш-карты и удалить ключ, если в этом конкретном году есть только один победитель. Когда я пытаюсь использовать этот метод, он удаляет весь ключ и значение, независимо от того, было ли в этом году более одного победителя. (например, в 1993 году победителями стали Нельсон Мандела и Фредерик Виллем де Клерк, если я пытаюсь удалить только Нельсон Мандела, вся запись с 1993 года ушел)Как удалить значение массива String из хэш-карты в java?

public void removeWinner(String nameOfWinnerToRemove) 

    {Iterator <HashMap.Entry<Integer, String[]>> it = winners.entrySet().iterator(); 
    while(it.hasNext()) 
    { 
     HashMap.Entry<Integer, String[]> entry = it.next(); 
     for(int i = 0; i < entry.getValue().length; i++) 

     { 
      if(entry.getValue()[i].equalsIgnoreCase(nameOfWinnerToRemove)) 
      { 
       it.remove(); 


      } 
     } 
    } 

} 

ответ

1

просто использовать этот

myMap.get(yourKey).remove(yourValue); 

более ясное:

Это будет работать, если значение List строк

winners.get(entry.getKey()).remove(nameOfWinnerToRemove); 

Если значения array

ArrayUtils.removeElement(winners.get(entry.getKey()), nameOfWinnerToRemove); 

это it.remove(); удалит всю ключевую ценность пары

обновление:

Загрузка и импорт org.apache.commons.lang3

Загрузить Jar: http://www.java2s.com/Code/Jar/c/Downloadcommonlang3jar.htm

+0

Метод «удалить» не существует на массивах. Это будет работать, только если он будет использовать List. Вероятно, вы должны указать это в своем ответе. – Neil

+0

Привет @Neil, Обновлен ответ. Подумайте об увеличении голосов – Backtrack

+0

Удалено нисходящее. – Neil

2

Вы делаете it.remove();, который удалит всю запись (пара ключ-значение) из HashMap, а не только конкретный победитель из значения.

Вы должны сделать что-то вроде этого:

if(entry.getValue()[i].equalsIgnoreCase(nameOfWinnerToRemove)) 
    { 
     /* Prepare a new value string without the name you want to remove */ 
     it.put(/* Key */, /* New Value */); //Doing this will overwrite the entry so you don't have to remove and re-add 
    } 
1
  1. Создать новый массив не-соответствия победителей
  2. Установите новый массив в качестве нового значения
  3. Извлеките ключ-значение- pair, если массив имеет только один элемент.

Это может быть похоже на следующее (Замена массива со списком для более простого использования):

public void removeWinner(String nameOfWinnerToRemove) { 
    final Map<String, List<String>> winnerMapping = new HashMap<>(); 
    final Iterator<Map.Entry<String, List<String>>> iterator = winnerMapping.entrySet().iterator(); 

    while (iterator.hasNext()) { 
     final List<String> winners = iterator.next().getValue(); 
     final List<String> matchingWinners = new ArrayList<>(); 

     for (final String winner : winners) { 
      if (winner.equalsIgnoreCase(nameOfWinnerToRemove)) { 
       matchingWinners.add(winner); 
      } 
     } 

     winners.removeAll(matchingWinners); 

     if (winners.size() == 1) { 
      iterator.remove(); 
     } 
    } 
} 
0

it - это итератор ввода карты, поэтому it.remove() удалит всю запись (отображение ключа в список авторов).Вам нужно только удалить его, если список пуст, так что это двухступенчатый процесс:

  1. Определить, нужно ли удалить победитель, и удалить их, если соответствие
  2. Всякий раз, когда вы удаляете победитель из список, проверьте, нужно ли также удалить весь введенный

вы должны использовать List<String> для списка победителей вместо String[], это легче манипулировать.

Тогда вы могли бы использовать этот подход:

public void removeWinner(String nameOfWinnerToRemove) { 

    Iterator <HashMap.Entry<Integer, String[]>> it = winners.entrySet().iterator(); 
    while(it.hasNext()) { 
     HashMap.Entry<Integer, String[]> entry = it.next(); 
     Iterator<String> listIt = entry.getValue().iterator(); 
     while (listIt.hasNext()) { 
      String value = listIt.next(); 
      if(value.equalsIgnoreCase(nameOfWinnerToRemove)) { 
       listIt.remove(); // remove the winner 

      } 
     } 

     if (entry.getValue().isEmpty()) { 
      it.remove(); // remove whole entry if empty 
     } 
    } 

} 
1

Ваша переменная «это» указывает на каждой записи карты, содержащей как ключ года и список имен. Если вы вызываете it.remove(), вы удаляете всю запись на карте. Что вы должны сделать, если найти имя в массиве, зависит от количества имен в списке. Если есть одно имя, тогда правильно называть его.remove(), поскольку это удаляет все. В противном случае мы хотим, чтобы значение записи в карте содержало новый массив без этого имени.

Ваш код должен выглядеть примерно следующим:

public void removeWinner(String nameOfWinnerToRemove) { 
    Iterator <HashMap.Entry<Integer, String[]>> it = winners.entrySet().iterator(); 
    while(it.hasNext()) { 
     HashMap.Entry<Integer, String[]> entry = it.next(); 
     List<String> namesList = new ArrayList<String>(Arrays.asList(entry.getValue())); 

     // Enter here if found and removed name 
     if(namesList.remove(nameOfWinnerToRemove)) { 
      if(namesList.size() > 0) { 
       // Set array without name 
       entry.setValue(namesList.toArray(entry.getValue()); 
      } else { 
       // New list is empty. Remove entry. 
       it.remove(); 
      } 
     } 
    } 
} 

Как правило, я хотел бы предложить вам использовать List или Collection, в отличие от массива, если вы обнаружите, что вам часто добавлять или удалять объекты , просто потому, что создание нового массива из старого требует конвертации в список в любом случае, и поэтому вы будете оптимизировать эти шаги.

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