2010-11-21 14 views
17

¿es posible cambiar las claves de una misma instancia de HashMap durante la iteración? Porque el conjunto de entrada de mapa no tiene un método entry.setKey(). Ahora lo que ocurre fuera es crear otra HashMap ...Cambio de claves HashMap durante la iteración

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()); 
    } 
} 

Respuesta

9

Usted debe mantener la información en otra colección de modificarlo después de iteración. Solo puede eliminar entradas usando iterator.remove() durante el iterador. HashMap contrato prohíbe mutarlo durante la iteración.

+5

* Nunca * puede cambiar un valor clave en un Mapa. – EJP

+0

así que desde el punto de vista del rendimiento, ¿la solución que tengo aquí está bien? Porque habrá miles de estas llamadas por hora – lisak

+0

@EJP lo que estoy cambiando aquí son solo las claves de un mapa – lisak

2

Hay cuatro tipos comunes de modificación que podría querer hacer a las claves o valores en un HashMap.

  1. Para cambiar una clave HashMap, busque el objeto de valor con get, luego quite la clave anterior y colóquela con la nueva clave.
  2. Para cambiar los campos en un objeto de valor, busque el objeto de valor por clave con get, luego use sus métodos setter.
  3. Para reemplazar completamente el objeto de valor, simplemente coloque un nuevo objeto de valor en la clave anterior.
  4. Para reemplazar el objeto de valor por uno basado en el anterior, busque el objeto de valor con get, cree un nuevo objeto, copie los datos desde el anterior y luego coloque el nuevo objeto bajo la misma clave.

Algo como este ejemplo.

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 
} 

espero que esto ayude a

17

Tal vez esto ayuda:

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

Si estoy iterando sobre el conjunto de claves, ¿se va a mostrar esta clave recién agregada en el conjunto de claves existente? – Ring

0

Lo mejor que puede hacer es copiar el mapa en uno nuevo con las modificaciones que desea, a continuación, volver este nuevo mapas y destruir el anterior. Sin embargo, me pregunto cuál es el impacto en el rendimiento de esta solución.

Cuestiones relacionadas