Kopie einer ArrayList: Fehler im Detail?

Status
Nicht offen für weitere Antworten.

clon

Mitglied
Hallo,

in einer Collection werden Objekte abgelegt. Von dieser Liste soll eine Kopie erzeugt werden, wobei eine Liste unabhängig von der anderen geändert werden soll.
Wird aber eine Liste geändert, ändert sich die andere auch, obwohl clone() und collections.copy() verwendet wurde. Weiß jemand, wo genau der Fehler zu suchen ist, denn eine Änderung mit Hilfe des new()-Operators funktioniert..

Im folgenden Codebeispiel wird eine eigene Klasse verwendet, das Problem dürfte aber auch mit normalen Strings auftreten.

Code:
import java.util.*;

public class cTest {

	public static void main(String[] args) {
		ArrayList a = new ArrayList();
		a.add(new A1("Binary", true));
		a.add(new A2("Double", 4.3553));
		//Struktur klonen ....
		ArrayList b = (ArrayList) a.clone();
		//und jetzt noch die Elemente reinkopieren ....
		Collections.copy(b, a);		

		System.out.println("Vor Änderung:");
		System.out.print("ArrayList A: [(" + ((A1) a.get(0)).m_string + ", " + ((A1) a.get(0)).m_bool + ")  ___  (");
		System.out.println(((A2) a.get(1)).m_string + ", " + ((A2) a.get(1)).m_double + ")]");
		System.out.print("ArrayList B: [(" + ((A1) b.get(0)).m_string + ", " + ((A1) b.get(0)).m_bool + ")  ___  (");
		System.out.println(((A2) b.get(1)).m_string + ", " + ((A2) b.get(1)).m_double + ")]");
		System.out.println("");
		
		b.set(0, new A1("xxxxxxxxxx", false)); // Bei zweitem Versuch, diese Zeile...
//		... mit dieser ersetzen: ((A1) a.get(0)).m_string = "Änderung";
		System.out.println("Nach Änderung:");
		System.out.print("ArrayList a: [(" + ((A1) a.get(0)).m_string + ", " + ((A1) a.get(0)).m_bool + ")  ___  (");
		System.out.println(((A2) a.get(1)).m_string + ", " + ((A2) a.get(1)).m_double + ")]");
		System.out.print("ArrayList b: [(" + ((A1) b.get(0)).m_string + ", " + ((A1) b.get(0)).m_bool + ")  ___  (");
		System.out.println(((A2) b.get(1)).m_string + ", " + ((A2) b.get(1)).m_double + ")]");		
	}
}


class A {
	public String m_string = "";
	protected A() {}
}

class A1 extends A {
	public boolean m_bool;

	A1(String string, boolean bool) {
		m_string = string;
		m_bool = bool;
	}
}

class A2 extends A {
	public double m_double;

	A2(String string, double dbl) {
		m_string = string;
		m_double = dbl;
	}
}

Die Ausgabe im ersten Fall ist mit b.set(0, new A1("xxxxxxxxxx", false)):

  • Vor Änderung:
    ArrayList A: [(Binary, true) ___ (Double, 4.3553)]
    ArrayList B: [(Binary, true) ___ (Double, 4.3553)]

    Nach Änderung:
    ArrayList a: [(Binary, true) ___ (Double, 4.3553)]
    ArrayList b: [(xxxxxxxxxx, false) ___ (Double, 4.3553)]
im zweiten Fall mit ((A1) a.get(0)).m_string = "Änderung":

  • Vor Änderung:
    ArrayList A: [(Binary, true) ___ (Double, 4.3553)]
    ArrayList B: [(Binary, true) ___ (Double, 4.3553)]

    Nach Änderung:
    ArrayList a: [(Änderung, true) ___ (Double, 4.3553)]
    ArrayList b: [(Änderung, true) ___ (Double, 4.3553)]

Gruß&Danke
 
Die copy-Methode ist wie folgt definiert:

Code:
public static void copy( List dest, List src ) { 
    try { 
        for (ListIterator di=dest.listIterator(), si=src.listIterator(); si.hasNext(); ) { 
            di.next();
            di.set(si.next()); 
        } 
    } catch(NoSuchElementException e) { // von di.next() 
        throw new IndexOutOfBoundsException("Source does not fit in dest."); 
    }
}

Es werden also keine Objekte gecloned, sondern lediglich Referenzen kopiert. Insofern ist klar, daß das einfache Überschreiben eines Objekts beide Listen ändert, während set(new ...) die Referenz der einen Liste ändert, wovon die andere unberührt bleibt.
 
Ok danke,
das hatte mich nämlich gewundert, denn eine Änderung während des Debug-Modus hatte auch Auswirkungen auf beide Listen..
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben