Estoy tratando de mantener un contenedor temporal de una clase que contiene miembro :

HashMap<Integer,myObject> myobjectHashMap

Una clase llamada myobjectsList

Entonces me

myojbectsListA = new myojbectsList();
myojbectsListB = new myobjectsList();

a continuación: Añadir algunos hashmap elementos a Un (like2)

luego

myobjectListB = myobjectListA; //B has 2

a continuación: Añadir hashmap elementos de A; (4 más)

a continuación, volver a a los elementos almacenados en B;

myobjectListA = myobjectListb;

pero cuando hago esto B crece con Un tiempo estoy agregando hashmap elementos de A.
Ahora tiene 6 artículos en ella, debido a B 6.

Quiero tener Un original de 2 todavía al final después de la última assingment
en C++ que me gustaría utilizar la copia con los objetos, lo que es el java equivalente?

Añadido: OK me dejó algo que explica esto.MyObjectsList no contiene el HashMap, se deriva de una clase MyBaseOjbectsList que tiene el HashMap miembro y MyObjectsList se extiende MyBaseOjbectsList. Hace una diferencia.?

  • Puedes publicar un SSCCE para dar una mejor comprensión de lo que has hecho hasta ahora?
  • Los objetos deben implementar la interfaz Cloneable, de lo contrario tareas como MyObjectB = MyObjectA simplemente decirle a la JVM que ambas variables apuntan a la misma ubicación en la memoria. No son dos objetos distintos.
  • Por cierto, la inmensa lenguaje (prácticamente una ley) es capitalizar los nombres de clase. Para hacer una de sus ejemplos mucho más legible para aquellos de nosotros que usar esas cosas tan rápida de las señales, mientras que el escaneo de código de ejemplo.
  • para agregar en @KevinWelker también ayuda a que el resaltador de sintaxis resaltar los nombres de clase
  • Gracias, pero trató de hacer cloneable, los hizo crecer cuando uno creció. Yo no quiero eso.
  • por favor comparta sus cloneable código. Vas a tener que escribir la aplicación para usted mismo. Mediante la creación de noticias y la asignación de valores…etc ¿se necesita un profundo vs copia superficial? …etc 🙂

InformationsquelleAutor user691305 | 2012-04-09

10 Comentarios

  1. 212

    Si usted desea una copia de la HashMap que usted necesita para construir uno nuevo.

    myobjectListB = new HashMap<Integer,myObject>(myobjectListA);

    Esto creará un (poco profundas) copia del mapa.

    • o si ya está creado, el uso myObjectListB.addAll(myObjectListA)
    • Tal vez no estoy entendiendo esto, pero yo no necesito una copia del mapa. Necesito una copia de la clase que contiene el mapa. ? Hay para myObjectListB tiene que ser una clase derivada de MyojbectsList no un hashmap.
    • También no entiendo la aplicación de «addAll(myOjbejctListA)»
    • Welker, addAll es para HashSet. putAll es para HashMap.
    • No trabajo. En mi caso, la «nueva» variable se sigue apuntando al mismo objeto.
    • He mencionado que, que es lo que «copia superficial» significa que, Si usted necesita una copia en profundidad a tener que recorrer el mapa y copiar lo que usted necesita.

  2. 14

    También puede utilizar

    clone()

    Método para copiar todos los elementos de un hashmap a otro hashmap

    Programa para copiar todos los elementos de un hashmap a otro

    import java.util.HashMap;
    
    public class CloneHashMap {    
         public static void main(String a[]) {    
            HashMap hashMap = new HashMap();    
            HashMap hashMap1 = new HashMap();    
            hashMap.put(1, "One");
            hashMap.put(2, "Two");
            hashMap.put(3, "Three");
            System.out.println("Original HashMap : " + hashMap);
            hashMap1 = (HashMap) hashMap.clone();
            System.out.println("Copied HashMap : " + hashMap1);    
        }    
    }

    fuente : http://www.tutorialdata.com/examples/java/collection-framework/hashmap/copy-all-elements-from-one-hashmap-to-another

    • Puede, pero probablemente no porque Cloneable es esencialmente roto, por Joshua Bloch Efectiva de Java #11.
    • también, tenga en cuenta que clone() devuelve una copia superficial.
    • Lo que hace poco profundas, incluso decir? Si no copia el mapa exactamente (con claves/valores intactos), ¿por qué molestarse? Así se podría crear un nuevo mapa, a la derecha?
    • superficial significa que no puede copiar cualquier objetos anidados y sus objetos anidados…
    • Si usted mira en la fuente, todos los clone() que hace es crear un nuevo HashMap y putAll todo. Es completamente inútil.
  3. 11

    La diferencia es que en C++ el objeto está en la pila, mientras que en Java, el objeto está en el montón. Si a y B son Objetos, en cualquier momento en Java que hacer:

    B = A

    A y B apuntan al mismo objeto, de modo que cualquier cosa que usted realice a Un que hacer para B y viceversa.

    El uso de nuevas HashMap() si desea que dos objetos diferentes.

    Y puede utilizar Map.putAll(...) para copiar datos entre dos Mapas.

    • Es que lo mismo que decir que Java es todo por referencia y C++ es a veces de referencia y, a veces, de valor? Pero yo no quiero un HashMap, yo wan no una copia duplicada de la clase I, se puede utilizar como almacenamiento temporal.
    • No tengo acceso a el HashMap en la clase base. De nuevo, tengo que trabajar con las clases que derivan de la base. No puedo acceder a la HashMap en ella.
  4. 6

    Hay un pequeño (GRAN) eufemismo aquí. Si desea copiar un HashMap con estructuras anidadas, HashMap.putAll() se copia por referencia, ya que no sabe cómo es la copia exacta de su objeto. Por ejemplo:

    import java.util.*;
    class Playground {
        public static void main(String[ ] args) {
            Map<Integer, Map<Integer,List<Float>>> dataA = new HashMap<>();
            Map<Integer, Map<Integer,List<Float>>> dataB = new HashMap<>();
    
            dataA.put(1, new HashMap<>());
            dataB.putAll(dataA);
    
            assert(dataB.get(1).size() == 0);
    
            dataA.get(1).put(2, new ArrayList<>());
    
            if (dataB.get(1).size() == 1) { //true
                System.out.println(
                    "Sorry object reference was copied - not the values");
            }
        }
    }

    Así que, básicamente, usted necesitará copiar los campos de sí mismo como aquí

    List <Float> aX = new ArrayList<>(accelerometerReadingsX);
    List <Float> aY = new ArrayList<>(accelerometerReadingsY);
    
    List <Float> gX = new ArrayList<>(gyroscopeReadingsX);
    List <Float> gY = new ArrayList<>(gyroscopeReadingsY);
    
    Map<Integer, Map<Integer, Float>> readings = new HashMap<>();
    
    Map<Integer,List<Float>> accelerometerReadings = new HashMap<>();
    accelerometerReadings.put(X_axis, aX);
    accelerometerReadings.put(Y_axis, aY);
    readings.put(Sensor.TYPE_ACCELEROMETER, accelerometerReadings);
    
    Map<Integer,List<Float>> gyroscopeReadings = new HashMap<>();
    gyroscopeReadings.put(X_axis, gX);
    gyroscopeReadings.put(Y_axis, gY);
    readings.put(Sensor.TYPE_GYROSCOPE, gyroscopeReadings);
  5. 4

    En Java, cuando escribe:

    Object objectA = new Object();
    Object objectB = objectA;

    objectA y objectB son los mismos y en el punto a de la misma referencia. El cambio de una voluntad de cambio de los otros. Así que si usted cambia el estado de objectA (no su referencia) objectB reflejará ese cambio también.

    Sin embargo, si usted escribe:

    objectA = new Object()

    Luego objectB todavía está señalando el primer objeto creado (original objectA), mientras que objectA ahora apunta a un nuevo Objeto.

    • que explica el problema, ¿cuál es la solución? O es esta una de las limitaciones de la versión de Java con ningún trabajo alrededor?
    • Eso no es una limitación, es la forma en que funciona. Si quieres 2 objetos diferentes, la creación de 2 objetos, sólo puede crear un objeto, a continuación, todas las variables que apuntan a que los objetos son iguales.
    • Sugiero crear una nueva pregunta con todo el código correspondiente (lo ideal es un SSCCE) y explicar exactamente lo que usted está tratando de lograr.
    • la creación de un nuevo objeto y la aniquilación de los valores originales no es la meta. El objetivo es mantener los valores originales y el uso sólo de nuevo más tarde en una copia que recibió más nuevos valores.
    • Así que realmente depende del objeto. Si no proporciona una forma de crear una nueva copia del objeto, entonces es complicado debido a que el objeto no ha sido diseñado para ser copiado (tal vez a propósito, pero todavía se puede hacer uso de la reflexión). Si el objeto es implementar esa función (véase, por ejemplo, la respuesta con el constructor de copia de HashMap), a continuación, usted sólo tiene que utilizar el método.
    • copia de los constructores o de una copia estática de las fábricas tienden a ser el camino a seguir aquí.

  6. 2

    Ya que la pregunta sigue sin respuesta y he tenido un problema similar, voy a intentar responder a esta. El problema (como otros que ya se ha mencionado es que usted acaba de copiar las referencias al mismo objeto y por lo tanto a modificar en la copia también va a modificar el origen del objeto. Así que lo que tienes que hacer es copiar el objeto (su mapa de valor en sí mismo. El extremo manera más fácil de hacerlo es hacer que todos sus objetos de aplicación de la serializeable de la interfaz. A continuación, serializar y deserializar el mapa para obtener una copia real. Usted puede hacer esto por usted mismo o utilizar el apache commons SerializationUtils#clone (), que puede encontrar aquí: https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/SerializationUtils.html Pero ser conscientes de que este es el método más sencillo, pero es una tarea costosa para serializar y deserializar un montón de objetos.

  7. 2

    Si queremos copiar un objeto en Java, existen dos posibilidades que debemos considerar: un copia superficial y un copia profunda.

    La copia superficial es el enfoque cuando nosotros sólo copia los valores de campo. Por lo tanto, la copia puede ser dependiente en el objeto original. En el copia profunda enfoque, nos aseguramos de que todos los objetos en el árbol están profundamente la copia, así que la copia no es dependiente de ninguna anterior objeto existente que podría cambiar nunca.

    Esta pregunta es la definición perfecta para la aplicación de la copia profunda enfoque.

    Primer lugar, si usted tiene una simple HashMap<Integer, List<T>> mapa, a continuación, acabamos de crear una solución como esta. La creación de una nueva instancia de la List<T>.

    public static <T> HashMap<Integer, List<T>> deepCopyWorkAround(HashMap<Integer, List<T>> original)
    {
        HashMap<Integer, List<T>> copy = new HashMap<>();
        for (Map.Entry<Integer, List<T>> entry : original.entrySet()) {
            copy.put(entry.getKey(), new ArrayList<>(entry.getValue()));
        }
        return copy;
    }

    Esta usa Stream.collect() método para crear el clon mapa, sino que utiliza la misma idea que el anterior método.

    public static <T> Map<Integer, List<T>> deepCopyStreamWorkAround(Map<Integer, List<T>> original)
    {
        return original
                .entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, valueMapper -> new ArrayList<>(valueMapper.getValue())));
    }   

    Pero, si las instancias dentro de T también objetos mutables tenemos un gran problema. En este caso una verdadera copia profunda es una alternativa que soluciona este problema. Su ventaja es que, al menos, cada objeto mutable en el gráfico de objeto de forma recursiva copiado. Dado que la copia no es dependiente de ninguna objeto mutable que se creó anteriormente, que no puede ser modificado por accidente, como vimos con la copia superficial.

    Para resolver esta copia profunda implementaciones va a hacer el trabajo.

    public class DeepClone
    {
    public static void main(String[] args)
    {
    Map<Long, Item> itemMap = Stream.of(
    entry(0L, new Item(2558584)),
    entry(1L, new Item(254243232)),
    entry(2L, new Item(986786)),
    entry(3L, new Item(672542)),
    entry(4L, new Item(4846)),
    entry(5L, new Item(76867467)),
    entry(6L, new Item(986786)),
    entry(7L, new Item(7969768)),
    entry(8L, new Item(68868486)),
    entry(9L, new Item(923)),
    entry(10L, new Item(986786)),
    entry(11L, new Item(549768)),
    entry(12L, new Item(796168)),
    entry(13L, new Item(868421)),
    entry(14L, new Item(923)),
    entry(15L, new Item(986786)),
    entry(16L, new Item(549768)),
    entry(17L, new Item(4846)),
    entry(18L, new Item(4846)),
    entry(19L, new Item(76867467)),
    entry(20L, new Item(986786)),
    entry(21L, new Item(7969768)),
    entry(22L, new Item(923)),
    entry(23L, new Item(4846)),
    entry(24L, new Item(986786)),
    entry(25L, new Item(549768))
    ).collect(entriesToMap());
    Map<Long, Item> clone = DeepClone.deepClone(itemMap);
    clone.remove(1L);
    clone.remove(2L);
    System.out.println(itemMap);
    System.out.println(clone);
    }
    private DeepClone() {}
    public static <T> T deepClone(final T input)
    {
    if (input == null) return null;
    if (input instanceof Map<?, ?>) {
    return (T) deepCloneMap((Map<?, ?>) input);
    } else if (input instanceof Collection<?>) {
    return (T) deepCloneCollection((Collection<?>) input);
    } else if (input instanceof Object[]) {
    return (T) deepCloneObjectArray((Object[]) input);
    } else if (input.getClass().isArray()) {
    return (T) clonePrimitiveArray((Object) input);
    }
    return input;
    }
    private static Object clonePrimitiveArray(final Object input)
    {
    final int length = Array.getLength(input);
    final Object output = Array.newInstance(input.getClass().getComponentType(), length);
    System.arraycopy(input, 0, output, 0, length);
    return output;
    }
    private static <E> E[] deepCloneObjectArray(final E[] input)
    {
    final E[] clone = (E[]) Array.newInstance(input.getClass().getComponentType(), input.length);
    for (int i = 0; i < input.length; i++) {
    clone[i] = deepClone(input[i]);
    }
    return clone;
    }
    private static <E> Collection<E> deepCloneCollection(final Collection<E> input)
    {
    Collection<E> clone;
    if (input instanceof LinkedList<?>) {
    clone = new LinkedList<>();
    } else if (input instanceof SortedSet<?>) {
    clone = new TreeSet<>();
    } else if (input instanceof Set) {
    clone = new HashSet<>();
    } else {
    clone = new ArrayList<>();
    }
    for (E item : input) {
    clone.add(deepClone(item));
    }
    return clone;
    }
    private static <K, V> Map<K, V> deepCloneMap(final Map<K, V> map)
    {
    Map<K, V> clone;
    if (map instanceof LinkedHashMap<?, ?>) {
    clone = new LinkedHashMap<>();
    } else if (map instanceof TreeMap<?, ?>) {
    clone = new TreeMap<>();
    } else {
    clone = new HashMap<>();
    }
    for (Map.Entry<K, V> entry : map.entrySet()) {
    clone.put(deepClone(entry.getKey()), deepClone(entry.getValue()));
    }
    return clone;
    }
    }
  8. 0

    Lo asignar un objeto a otro, todo lo que estamos haciendo es copiar el referencia para el objeto, y no el contenido de la misma. Lo que usted necesita hacer es tomar su objeto B y copiar manualmente el contenido de Un objeto en él.

    Si haces esto a menudo, usted podría considerar la implementación de un clone() método en la clase que va a crear un nuevo objeto del mismo tipo, y copia todo su contenido en el nuevo objeto.

    • Clon hizo la misma cosa parecía no pasar la referencia.
    • También, cuando uno aumenta su HashMap recuento, la copia no demasiado, no quiero eso. Quiero idependent contenedores(en este caso las clases) del mismo tipo.
  9. 0

    Ya que el OP ha mencionado que no tienen acceso a la base de la clase dentro de la cual existe un HashMap – me temo que hay muy pocas opciones disponibles.

    Uno (dolorosamente lento y consume muchos recursos) forma de realizar una copia en profundidad de un objeto en Java es el abuso de la «Serializable» de la interfaz que muchas de las clases, ya sea intencionalmente o sin intención de ampliar y, a continuación, utilizar esta a serialise su clase para ByteStream. Después de la seriación usted tendrá un profundo copia del objeto en cuestión.

    Una guía para esto se puede encontrar aquí: https://www.avajava.com/tutorials/lessons/how-do-i-perform-a-deep-clone-using-serializable.html

  10. 0

    Desde Java 10 es posible utilizar

    Map.copyOf

    para la creación de un copia superficial, que es también inmutable. (Aquí es su Javadoc). Para un copia profunda, como se ha mencionado en este respuesta usted, necesitan algún tipo de valor mapper para hacer una copia de seguridad de valores. Usted no necesita una copia de claves, aunque, ya que debe ser inmutable.

Dejar respuesta

Please enter your comment!
Please enter your name here