2010-11-21 4 views
17

Можно ли изменять ключи одного и того же экземпляра HashMap во время итерации? Поскольку набор записей карты не имеет метода entry.setKey(). Теперь то, что я могу думать, это прочь создать еще один HashMap ...Изменение ключей HashMap во время итерации

MultipartParsingResult parsingResult = parseRequest(request); 

Map<String, String[]> mpParams = parsingResult.getMultipartParameters(); 
Map<String, String[]> mpParams2 = new HashMap<String, String[]>(); 

Iterator<Entry<String,String[]>> it = mpParams.entrySet().iterator(); 

while (it.hasNext()) { 
    Entry<String,String[]> entry = it.next(); 
    String name = entry.getKey(); 

    if (name.startsWith(portletNamespace)) { 
     mpParams2.put(name.substring(portletNamespace.length(), name.length()), entry.getValue()); 
    } 
    else { 
     mpParams2.put(name, entry.getValue()); 
    } 
} 

ответ

9

Вы должны хранить информацию в другой коллекции, чтобы изменить его после итерации. Вы можете удалить запись только с помощью iterator.remove() во время итератора. HashMap контракт запрещает мутировать его во время итерации.

+5

Вы можете * никогда * изменять значение ключа на карте. – EJP

+0

так с точки зрения производительности, это решение, которое у меня здесь в порядке? Потому что там будут тысячи этих звонков в час. – lisak

+0

@EJP. Я меняю здесь только ключи от карты. – lisak

2

Существует четыре общих типа модификаций, которые вы можете сделать с ключами или значениями в HashMap.

  1. Чтобы изменить ключ HashMap, вы увидите объект значения с помощью get, затем удалите старый ключ и поместите его новым ключом.
  2. Чтобы изменить поля в объекте значения, посмотрите объект value вверх по ключу с помощью get, а затем используйте его методы настройки.
  3. Чтобы полностью заменить объект значения, просто поместите новый объект значения в старый ключ.
  4. Чтобы заменить объект значения на один на основе старого, посмотрите объект value с помощью get, создайте новый объект, скопируйте данные из старого, затем поместите новый объект под тот же ключ.

Что-то вроде этого примера.

static class Food 
    { 
    // ------------------------------ FIELDS ------------------------------ 

    String colour; 

    String name; 

    float caloriesPerGram; 
    // -------------------------- PUBLIC INSTANCE METHODS -------------------------- 

    public float getCaloriesPerGram() 
     { 
     return caloriesPerGram; 
     } 

    public void setCaloriesPerGram(final float caloriesPerGram) 
     { 
     this.caloriesPerGram = caloriesPerGram; 
     } 

    public String getColour() 
     { 
     return colour; 
     } 

    public void setColour(final String colour) 
     { 
     this.colour = colour; 
     } 

    public String getName() 
     { 
     return name; 
     } 

    public void setName(final String name) 
     { 
     this.name = name; 
     } 

    public String toString() 
     { 
     return name + " : " + colour + " : " + caloriesPerGram; 
     } 

    // --------------------------- CONSTRUCTORS --------------------------- 

    Food(final String name, final String colour, final float caloriesPerGram) 
     { 
     this.name = name; 
     this.colour = colour; 
     this.caloriesPerGram = caloriesPerGram; 
     } 
    } 

// --------------------------- main() method --------------------------- 

/** 
* Sample code to TEST HashMap Modifying 
* 
* @param args not used 
*/ 
public static void main(String[] args) 
    { 
    // create a new HashMap 
    HashMap<String, Food> h = new HashMap<String, Food>(149 
      /* capacity */, 
      0.75f 
      /* loadfactor */); 

    // add some Food objecs to the HashMap 
    // see http://www.calorie-charts.net for calories/gram 
    h.put("sugar", new Food("sugar", "white", 4.5f)); 
    h.put("alchol", new Food("alcohol", "clear", 7.0f)); 
    h.put("cheddar", new Food("cheddar", "orange", 4.03f)); 
    h.put("peas", new Food("peas", "green", .81f)); 
    h.put("salmon", new Food("salmon", "pink", 2.16f)); 

    // (1) modify the alcohol key to fix the spelling error in the key. 
    Food alc = h.get("alchol"); 
    h.put("alcohol", alc); 
    h.remove("alchol"); 

    // (2) modify the value object for sugar key. 
    Food sug = h.get("sugar"); 
    sug.setColour("brown"); 
    // do not need to put. 

    // (3) replace the value object for the cheddar key 
    // don't need to get the old value first. 
    h.put("cheddar", new Food("cheddar", "white", 4.02f)); 

    // (4) replace the value object for the peas key with object based on previous 
    Food peas = h.get("peas"); 
    h.put("peas", new Food(peas.getName(), peas.getColour(), peas.getCaloriesPerGram() * 1.05f)); 

    // enumerate all the keys in the HashMap in random order 
    for (String key : h.keySet()) 
     { 
     out.println(key + " = " + h.get(key).toString()); 
     } 
    }// end main 
} 

Я надеюсь, что это помогает

17

Может быть, это помогает:

map.put(newkey,map.remove(oldkey)); 
+0

Если я повторяюсь по набору ключей, это новый добавленный ключ будет отображаться в существующем наборе ключей? – Ring

0

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

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