2011-04-28 53 views
10

Map.putAll es equivalente a llamar al Map.put(k, v) en el mapa una vez por cada asignación desde la clave k hasta el valor v en el mapa especificado. Entonces, con el aspecto funcional, ambos son lo mismo.Diferencia entre los métodos Map.put y Map.putAll?

Entonces, tengo curiosidad por saber cuáles son las otras diferencias y cuándo usar cuál?

Respuesta

4

Utilice putAll(Map) cuando tenga un Mapa de varios valores que desee agregar a su Mapa, y use put(K,V) cuando tenga uno o un par de valores que quiera agregar a su Mapa.

putAll(Map) en la mayoría de las implementaciones simplemente llama a put(K,V) en un bucle, lea el source.

+3

Esa última línea es un poco engañosa. Aunque AbstractMap _does_ funciona como usted lo describe, otras implementaciones concretas de Map no funcionan. –

+0

@Paul: +1, tienes razón. Es un poco simplificado, pero creo que la mayoría de las implementaciones compatibles con la interfaz de Map funcionan de esa manera, ya que la interfaz de Map no da mucho margen de acción. –

1

putAll() method

Copies all the elements from a specified map to the current Map object.  

put() method

Adds an element at a specific key entry to a Map object. 
5

Como se afirma en documentos:

Map.put

Asocia el valor especificado con la clave especificada en este mapa (operación opcional). Si el mapa anteriormente contenía una asignación para la clave , el valor anterior se reemplaza por el valor especificado . (Un mapa m se dice que contiene una asignación para una clave k si, y sólo si m.containsKey (k) volvería cierto.)

le permite poner un único par clave-valor en el mapa .

Map.putAll

todas las copias de las asignaciones del mapa especificado a este mapa (opcional operación ). El efecto de esta llamada es equivalente al de poner put (k, v) en este mapa una vez para cada asignación desde la clave k hasta el valor v en el mapa especificado. El comportamiento de esta operación es indefinido si el mapa especificado es modificado mientras la operación está en progreso .

poner todos los datos de un mapa a otro mapa.


cuándo usar cuál?

Si desea copiar los datos completos de un mapa a otro puede utilizar map.putAll demás simplemente puede añadir un par clave-valor con map.put.


Map.putAll es equivalente a la de llamando map.put (k, v) en el mapa una vez para cada asignación de clave k al valor de v en el mapa especificado. Así que con el aspecto funcional ambos son iguales.

n cuando se implementa un mapa en hasmap a continuación para copiar un mapa a otro usando puesto (k, v) se llevará a un mayor esfuerzo y se puede decir más de codificación utilizando putAll (m) podemos copiar mapa con una sola línea código.

0

Map.put(Object key, Object value) le permite agregar una sola entrada mientras que Map.putAll(Map t) agrega todas las entradas contenidas en el Mapa t al Mapa especificado. putAll() es útil al combinar dos mapas.

4

Dado que Map es solo una interfaz, sin ninguna implementación, no puede haber ninguna diferencia entre una putAll y una put repetida que no sea la diferencia funcional, es decir, ninguna. Si observa las implementaciones individuales de Map (por ejemplo, HashMap), puede haber un problema de rendimiento. Un putAll debe ser al menos tan eficiente como una repetición para cualquier implementación razonable, pero puede ser exactamente igual.

+3

+1 - me ganaste ... y respondiste la pregunta del OP en lugar de solo recitar los detalles de la API. –

9

Depende.

put y putAll son métodos de interfaz, por lo cada implementación real de esa interfaz garantizará que el método put pone un único par clave/valor en el mapa whil putAll pondrá todos los pares clave/valor de la fuente.

Pero depende del implementador cómo hacerlo y qué hacer además (internamente).

Claro, una implementación trivial llamaría a put para cada una de las entradas del mapa fuente, pero tal vez alguien invente otro método para lograr el objetivo. O putAll hará algunas otras cosas internas del mapa antes/después/al ingresar pares de adición.

Mi regla general: si tiene que poner todos los pares de clave/valor de un mapa a otro, entonces confíe en la inteligencia del implementador y use el método putAll. Siempre hay una buena posibilidad de que proporcione un mejor rendimiento que llamando al put para todos los pares manualmente.

2

La diferencia más obvia es la colección sincronizada.

Para un mapa sincrónico, putAll agregará todas las entradas como una operación única. Si tiene dos hilos que intentan poner todas las mismas teclas con diferentes valores, solo obtendrá un conjunto completo de valores. es decir, del primer o segundo subproceso, pero no de alguna combinación.

Si usa put() repetidamente en dos subprocesos, puede obtener cualquier combinación de valores retenidos que pueden no ser una combinación válida.


He visto/implementado operaciones transaccionales para put() y putAll(). Cuando putAll es transaccional, se agregarán todas o ninguna clave/valor. p.ej. si una clave o valor no se puede agregar por alguna razón. Si está utilizando put(), solo se detendrá la clave/valor indiviudal (y posiblemente no agregado), realizando una actualización potencialmente incompleta.

1

Veo un gran beneficio en el rendimiento cuando uso putAll en lugar de put. Ver el programa de ejemplo siguiente:

clase pública Sampletest {

public static void main(final String[] args) { 

    final Map<String, String> testMap = new HashMap<>(); 
    final Map<String, String> testMap2 = new HashMap<>(); 

    final LocalDateTime startTestTime = LocalDateTime.now(); 
    for(int i=0; i < 1000000; i++) { 
     testMap.put(i+"", i+""); 
    } 
    final LocalDateTime endTestTime = LocalDateTime.now(); 
    System.out.println("<<<<<<<<<Time for put>>>>>>>>>>>"); 
    System.out.println(ChronoUnit.MILLIS.between(startTestTime, endTestTime)); 

    final LocalDateTime startTestTime1 = LocalDateTime.now(); 
    testMap2.putAll(testMap); 
    final LocalDateTime endTestTime1 = LocalDateTime.now(); 
    System.out.println("<<<<<<<<<Time for put all>>>>>>>>>>>"); 
    System.out.println(ChronoUnit.MILLIS.between(startTestTime1, endTestTime1)); 
} 

}

Esto devuelve (en milisegundos):

<<<<<<<<<Time for put>>>>>>>>>>> 
1934 
<<<<<<<<<Time for put all>>>>>>>>>>> 
116 

Conclusión: putAll() es definitivamente más Performant than put() con las renuncias de responsabilidad a continuación. 1. Este resultado está en mi máquina (es decir, depende de la configuración de la máquina). Pero todavía ves una gran diferencia. 2. Como se mencionó anteriormente Map es una interfaz, por lo que el rendimiento dependerá de la implementación; he considerado HashMap, ya que es ampliamente utilizado. Por lo tanto, si el rendimiento es una restricción, puede preferir putAll() para HashMap al menos.

Cuestiones relacionadas