# ArrayList kopieren?



## hdi (24. Mrz 2008)

hey, habe eine statische ArrayList. 
Diese ArrayList sollen zwei Panels kriegen, jeweils als eigene Instanz:
(is in pseudo-code, es geht hier nicht um einzelheiten)

class MeinPanel{

      private ArrayList myList

      myList = new ArrayList (DieKlasseMitDerStatischenListe.getArrayList);

}

so, wegen dem new-Operator sollten doch jetzt beide Instanzen der Klasse MeinPanel
eine eigene, private Instanz "myList" haben. Und das sollte doch eig. unterschiedlcieh Objekte sein oder?

Wenn ich allerdings den HashCode von beiden "myLists" prüfe, dann ist es der selbe.

Wieso? Ich dachte bei jedem "new" wird ein neues Objekt erstellt.
Und wie kann ich jetzt diese eine statische Liste beiden Panels geben, aber so, dass es 
intern verschiedene Listen sind?

Danke


----------



## maki (24. Mrz 2008)

http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html#hashCode()

Es sind zwei Listen, allerdings mit denselben Elementen.


----------



## Marco13 (24. Mrz 2008)

Wenn zwei Objekte identisch sind, dann haben sie den gleichen hashCode
Wenn zwei Objekte den gleichen hashCode haben, sind sie NICHT NOTWENDIGERWEISE identisch.


----------



## Janus (24. Mrz 2008)

soll heissen: dein code ist korrekt


----------



## hdi (24. Mrz 2008)

hey, mein code ist nicht korrekt, denn man merkt dass das eine panel objekte des anderen modifiziert.

okay, dann brauch ich halt jedes element der statischen arrayliste zwei mal. mich wundert aber, dass es dafür
keine methode in der API gibt. 

clone() kopiert nämlich auch keine Objekte, sondern nur eine "shallow copy".

muss ich halt in einer for-schleife alles element für element dublizieren. ich frag trotzdem sicherheitshalber,
weil ichs echt komisch finde: gibt es keine methode, mit der man eine "harte" kopie erstellen kann?
sodass es wirklich komplett andre elemente sind?

danke

*edit*

da war ich wohl zu vorschnell:
und zwar sind die Elemente meiner statischen ArrayList leider Objekte einer abstrakten Klasse.
d.h.: ich kann keine neuen Objekte davon erstellen, außer ich überprüfe erst total umständlich was es ist
und erstelle dann dementsprechend ein neues Objekt.
Aber das wird doch schön langsam echt zu umständlich, da muss es doch n bessern weg geben?

hier mal der code, damit das mal eindeutig klar ist:


```
public class Pool {

    private static ArrayList<Steerable> elements;
    private static Random gen;

    public static void init() {

        gen = new Random();
        elements = new ArrayList<Steerable>(5000);
        int count = 500;
        while (count > 0) {
            if (gen.nextInt(100) == 99) {
                elements.add(new Diamond());
            } else {
                Bubble b1 = new Bubble(gen.nextInt(6));
                Bubble b2 = new Bubble(gen.nextInt(6));
                elements.add(new Duals(b1, b2));
            }
            count--;
        }
    }

    public static ArrayList<Steerable> getPool() {
        return elements;
    }
}
```

und mein Panel, von dem ich zwei Instanzen mache, sagt in der entsprechenden Methode:


```
private ArrayList<Steerable> pool;

pool = new ArrayList<Steerable> (Pool.getPool());
```

das geht also eben nicht, weil jedes Panel seine EIGENEN Objekte haben soll.
In einer Schleife kopieren geht aus o.g. Grund nicht, ich kann in einer schleife nicht sagen:


```
pool.add( new AbstractClass(Pool.getPool().get(i)));
```

weil das ganze eben abstrakt ist.
Also wie ne ordentliche Kopie?


----------



## maki (24. Mrz 2008)

> und zwar sind die Elemente meiner statischen ArrayList leider Objekte einer abstrakten Klasse.


Objekte einer Abstrakten Klasse? 
Bestimmt nicht 

Ansonsten musst du alles mitkopieren was nicht immutable ist um eine sog. "deep copy" zu erhalten.


----------



## JavaFred (24. Mrz 2008)

hdi hat gesagt.:
			
		

> gibt es keine methode, mit der man eine "harte" kopie erstellen kann?
> sodass es wirklich komplett andre elemente sind?


Dafür gibt es keine Standardmittel. Die ArrayList kann ja nicht davon ausgehen, dass die in ihr enthaltenen Elemente klonbar sind. Da musst Du wohl Deine Elementklassen klonbar machen und dann selbst klonen.

Dazu solltest Du zunächst Dein Interface entsprechend anpassen:

```
interface Steerable extends Cloneable
{
	public Steerable clone();
}
```
Das "extends Cloneable" ist wichtig, damit es zur Laufzeit nicht zu einer CloneNotSupportedException kommt. Cloneable ist aber nur ein leeres Marker-Interface ohne Operationen (insbesondere ohne clone-Operation). Damit garantiert ist, dass jedes konkrete Steerable-Objekt auch wirklich clone implementiert, müssen wir diese Operation explizit in das Steerable-Interface mit aufnehmen, und zwar als public-Operation mit kovariantem Rückgabetyp (Steerable statt Object). Jetzt musst Du clone natürlich in allen implementierenden Klassen einbauen. Wie sehen denn die Klassen aus, die Steerable implementieren? Poste mal eine.

So, jetzt ist das tiefe Klonen nicht mehr besonders kompliziert:

```
public static ArrayList<Steerable> deepClone(ArrayList<Steerable> original)
{
	ArrayList<Steerable> klon = new ArrayList<Steerable>(original.size());
	for (Steerable s : original)
		klon.add(s.clone());
	return klon;
}
```

Der clone-Mechanismus ist in Java ziemlich gewöhnungsbedürftig. Wenn Du aber Exemplare unterschiedlicher Klassen in eine Liste packen und diese dann klonen willst, kommst Du kaum drum herum.


----------



## Guest (24. Mrz 2008)

hm.. also ich hab ja kein interface, sondern eine abstrakte klasse, die abstrakte methoden anbietet.
diese überschreiben die einzelnen konkreten Unterklassen.

Also so geht ja Cloneable nicht zu implementieren. Ich kann ja nich von nem Interface erben.


----------



## JavaFred (25. Mrz 2008)

Anonymous hat gesagt.:
			
		

> Also so geht ja Cloneable nicht zu implementieren.


Natürlich geht das. Dann sieht der Code halt ein bischen anders aus:


```
abstract class Steerable implements Cloneable 
{ 
    public abstract Steerable clone();

    // ...
    // Deine restlichen abstrakten Methoden
    // ...
}
```

Bitte eine Klasse posten, die von Steerable erbt. Und poste bitte auch mal Steerable, würde mich interessieren.


----------

