# java.util.List klonen



## Gast (19. Feb 2008)

Hallo!

Wei kann man java.util.List klonen ?

Grüße
gast


----------



## SlaterB (19. Feb 2008)

List l = new ArrayList(alteList);


----------



## Guest (21. Feb 2008)

hallo danke aber wenn sich der Inhalt von alteList
ändert, so ändert sich der Inhalt von l. 

Jedenfalls habe ich bei mir dieses Phänomen warum auch immer

Grüße
Gast


----------



## The_S (21. Feb 2008)

du müsstest die Objekte in der Liste natürlich auch "klonen".


----------



## Oli (21. Feb 2008)

Hallo,

List l = new ArrayList(alteList). l erhält nur die Referenz auf alte List. Somit ist es klar, dass sich die Inhalte ändern.

List l = alteList.clone() wäre hier der richtige Ansatz. Allerdings ist clone()  nicht visible in der Klasse List. 
Wenn du einen Vektor verwenden kannst ist es ein Einzeiler (wie oben), wenn nicht musst du die Funktion clone() aus List überschreiben.

Grüße Oli


----------



## SlaterB (21. Feb 2008)

> l erhält nur die Referenz auf alte List

? was hat die alte Liste dann noch damit zu tun?,
es wird eine neue Liste erstellt und alle Elemente eingefügt


----------



## maki (21. Feb 2008)

> List l = new ArrayList(alteList). l erhält nur die Referenz auf alte List. Somit ist es klar, dass sich die Inhalte ändern.


Das stimmt nicht.

Es wird eine neue Liste erstellt, welche eine Kopie der Werte aus der alten Liste hat.
Das Problem ist, dass es sich bei den Werten wahrscheinlich um Referenzen auf Objekte handelt, dadurch greift man sowohl über die neue Liste als durch die alte Liste immer auf diesselben Objekte zu.

Deep copy vs. Shallow copy eben



> List l = alteList.clone() wäre hier der richtige Ansatz. Allerdings ist clone() nicht visible in der Klasse List.
> Wenn du einen Vektor verwenden kannst ist es ein Einzeiler (wie oben), wenn nicht musst du die Funktion clone() aus List überschreiben.


Auch nicht richtig.

List ist keine Klasse sondern ein Interface, ArrayList bietet eine clone() Methode an, die macht aber nix anderes als der copy Konstruktor, eine shallow copy eben.

Vector zu verwenden wäre echt seltsam, da es nix am Problem ändert, sondern nur eine sehr alte Klasse ist, dazu auch noch synchronisiert und daher langsamer als eine ArrayList.
Vector sollte nicht mehr verwendet werden, ausser es muss sein.


----------



## Oli (21. Feb 2008)

Hallo,

Mit new ArrayList(alteList) erstellst du eine neue Liste l, die auf alteList referenziert. Das heißt, das l auf alteList zeigt. Probier folgendes:

List l = new List(alteList);
alteList = null;
Sting x = (String)l.getItem(0);

Das knallt....

Grüße Oli


----------



## maki (21. Feb 2008)

Oli hat gesagt.:
			
		

> Hallo,
> 
> Mit new ArrayList(alteList) erstellst du eine neue Liste l, die auf alteList referenziert. Das heißt, das l auf alteList zeigt. Probier folgendes:
> 
> ...


:autsch: 

Klar knallt das, aber das knallt auch wenn du die Zeile
alteList = null;
weglässt... eine leere Liste kann man nunmal nicht auslesen. 

Abgesehen davon scheinst du da ein paar Dinge zu verwechseln..


----------



## Oli (21. Feb 2008)

Hi,

naja ich gehe davon aus, dass alteList vorhanden und mit Daten gefüllt ist....

Grüße Oli


----------



## SlaterB (21. Feb 2008)

ist das hier versteckte Kamera? 

1.
das ganze knallt nicht, hast du das nicht selber ausprobiert, bevor du das hier postest?
von den ganzen Tippfehlern ganz zu schweigen

2.
selbst wenn deine Theorie stimmt und die neue Liste abenteuerlicherweise eine Referenz auf die alte Liste hätte,
würde es immer noch klappen ,
denn wenn du die lokale Variable alteList auf null setzt, dann wird dadurch ja nicht das Objekt selber zerstört
oder andere Referenzen auf dieses Objekt per Zauberhand auch auf null gesetzt..


```
public class Test
{
    public static void main(String[] args)
        throws Exception
    {
        List<String> alteList = new ArrayList<String>();
        alteList.add("Test");
        List l = new ArrayList(alteList);
        alteList = null;
        String x = (String)l.get(0);
        System.out.println(x);
    }
}
```



```
public class Test
{
    public static void main(String[] args)
        throws Exception
    {
        List<String> alteList = new ArrayList<String>();
        alteList.add("Test");
        List l = alteList;
        alteList = null;
        String x = (String)l.get(0);
        System.out.println(x);
    }
}
```


----------



## maki (21. Feb 2008)

> ist das hier versteckte Kamera? icon_wink.gif


lol 
Alternativ wäre auch Punked möglich 

Oli,

ein Konstruktor hat nicht viele Möglichkeiten, er kann

entweder ein neues Objekt erzeugen und eine referenz darauf zurückliefern

oder eine Exception werfen.

Magische Wege um eine referenz auf ein altes Objekt zuurückzuliefern gibt es aus einem Konstruktor nicht.

Bist du sicher dass du den Unterschied zwischen Referenz und Objekt verstanden hast?


----------



## Guest (21. Feb 2008)

Hallo Leute,

ich habe das Problem weiterhin noch..



> du müsstest die Objekte in der Liste natürlich auch "klonen".



wie ? 

Ich habe Java 1.4 im Einsatz.

Grüße
Gast


----------



## SlaterB (21. Feb 2008)

wenn die enthaltenen Objekte alle serialisierbar sind, dann kannst das zu einer einfachen Kopie nutzen:

http://www.maier-lenz.at/chlblog/2006/09/simple-java-deep-copy.html

zu Serialisierung:
http://www.tutego.com/javabuch/javainsel6/javainsel_12_012.htm


----------



## maki (21. Feb 2008)

Was für Objekte hast du denn in dieser Liste?
Du musst diese Objekte kopieren.

Bieten die einen Copy-Konstruktor, oder eine (statische) factory Methode, oder clone() oder etwas vergleichbares?


----------



## Guest (21. Feb 2008)

> Was für Objekte hast du denn in dieser Liste?


das sind Zeilen einer Tabelle. Ein spezielles Objekt. Wir autoamtisch angegelt als Proxyklasse
samt den getter und setter Methoden .

Du musst diese Objekte kopieren.
Das ja womit ich nicht klar komme


Muss etwa die Proxyklasse Clonable implementieren. Wenn ja
was muss ich noch für eine tiefe Kopie machen ?

Grüße
Gast


----------



## maki (21. Feb 2008)

Bleib weg von clone() und cloneable.

Besser:
- Copy Constructor
oder 
- statische Factory Methoden

Im Prinzip gehst du deine Liste mit einem Iterator durch, kopierst jedes Objekt, und steckst die Kopie des Objektes in eine neues Liste.


----------



## HoaX (21. Feb 2008)

@oli: es geht hier wie der titel sagt um java.util.List, nicht java.awt.List


----------

