Según tengo entendido, hay un par de formas (tal vez otras también) de crear una copia superficial de a Map
en Java:
Map<String, Object> data = new HashMap<String, Object>();
Map<String, Object> shallowCopy;
// first way
shallowCopy = new HashMap<String, Object>(data);
// second way
shallowCopy = (Map<String, Object>) ((HashMap<String, Object>) data).clone();
¿Se prefiere una forma sobre la otra y, de ser así, por qué?
Una cosa que vale la pena mencionar es que la segunda forma muestra una advertencia de "Reparto sin marcar". Así que tienes que agregar @SuppressWarnings("unchecked")
para evitarlo, lo cual es un poco irritante (ver más abajo).
@SuppressWarnings("unchecked")
public Map<String, Object> getDataAsMap() {
// return a shallow copy of the data map
return (Map<String, Object>) ((HashMap<String, Object>) data).clone();
}
java
map
clone
shallow-copy
dcp
fuente
fuente
Respuestas:
Siempre es mejor copiar usando un constructor de copias.
clone()
en Java está roto (ver SO: ¿Cómo anular correctamente el método de clonación? ).Josh Bloch sobre diseño: constructor de copias versus clonación
Bloch (quien, por cierto, diseñó e implementó el marco de la Colección) incluso fue más allá al decir que solo proporciona el
clone()
método solo "porque la gente lo espera". En realidad, NO recomienda usarlo en absoluto.Creo que el debate más interesante es si un constructor de copias es mejor que una fábrica de copias, pero esa es una discusión completamente diferente.
fuente
Ninguno de los dos: el constructor al que te refieres está definido para la implementación HashMap de un mapa (así como para otros) pero no para la interfaz del mapa en sí (por ejemplo, considera la implementación del proveedor de la interfaz del mapa: no encontrará ese constructor).
Por otro lado no es recomendable utilizar el
clone()
método, como explica Josh Bloch.Con respecto a la interfaz del Mapa (y de su pregunta, en la que pregunta cómo copiar un Mapa, no un HashMap), debe usar Map # putAll () :
Ejemplo:
fuente
Map
que tiene un constructor de copia, ¿no hay razón para no usar el constructor de copia, entonces?putAll
usas no necesitas saber si laMap
implementación que estás usando tiene un constructor de copia o no. Por lo tanto, un constructor de copia de cualquierMap
implementación es redundante.Copia un mapa sin conocer su implementación:
fuente
<K,V>
parámetros de tipo para ayudar a garantizar la seguridad del tipo.