4.5 Bibliotheksunterstützung von Arrays
4.5.1 Klonen kann sich lohnen – Arrays vermehren
Wollen wir eine Kopie eines Arrays mit gleicher Größe und gleichem Elementtyp schaffen, so nutzen wir dazu die Objektmethode clone().[ 126 ](Das ist gültig, da Arrays intern die Schnittstelle Cloneable implementieren. System.out.println( new int[0] instanceof Cloneable); gibt true zurück. ) Sie klont – in unserem Fall kopiert – die Elemente des Array-Objekts in ein neues.
int[] sourceArray = new int[ 6 ];
sourceArray[ 0 ] = 4711;
int[] targetArray = sourceArray.clone();
System.out.println( targetArray.length ); // 6
System.out.println( targetArray[ 0 ] ); // 4711
Im Fall von geklonten Objekt-Arrays ist es wichtig, zu verstehen, dass die Kopie flach ist. Die Verweise aus dem ersten Array kopiert clone() in das neue Array, es klont aber die referenzierten Objekte selbst nicht. Bei mehrdimensionalen Arrays wird also nur die erste Dimension kopiert, Unter-Arrays werden somit gemeinsam genutzt:
Point[] pointArray1 = { new Point(1, 2), new Point(2, 3) };
Point[] pointArray2 = pointArray1.clone();
System.out.println( pointArray1[ 0 ] == pointArray2[ 0 ] ); // true
Die letzte Zeile zeigt anschaulich, dass die beiden Arrays dasselbe Point-Objekt referenzieren; die Kopie ist flach, aber nicht tief.
4.5.2 Warum »können« Arrays so wenig?
Arrays haben ein Attribut length und eine Methode clone() sowie die von Object geerbten Methoden. Das ist nicht viel. Für Arrays gibt es keine Klassendeklaration, also auch keine .class-Datei, die Methoden deklariert. Es gibt auch keinen Java-Code wie bei anderen Klassen wie String, Arrays oder System, die mit Javadoc dokumentiert sind und folglich in der API-Dokumentation auftauchen. Da es unendlich viele Array-Typen gibt – hinter jedem beliebigen Typ kann [] gesetzt werden –, würde das auch unendlich viele Klassendeklarationen nach sich ziehen.
Das, was Arrays können, ist in der Java-Sprachdefinition (JLS) festgeschrieben. Bei jeder neuen Methode oder Änderung müsste die JLS angepasst werden, was unpraktisch ist. Natürlich wären Methoden wie sort(…), indexOf(…) auf Array-Objekten praktisch, aber zu viel Eingebautes in der Sprache ist nicht gut und auch die Dokumentation solcher Methoden will Oracle aus der JLS heraushalten, und so sind die Methoden in eine Extraklasse Arrays gewandert.
[»] Hinweis
Die Länge ist immer die Kapazität des Arrays. Es gibt keine Information darüber, wie viele Array-Elemente von uns in der Nutzung sind. Wenn das Array zum Beispiel 10 Elemente groß ist, aber nur die ersten 2 Positionen von uns verwendet werden, so müssen wir uns das selbst merken.
4.5.3 Array-Inhalte kopieren
Eine weitere nützliche statische Methode ist System.arraycopy(…). Sie kann auf zwei Arten arbeiten:
auf zwei schon existierenden Arrays: Ein Teil eines Arrays wird in ein anderes Array kopiert. arraycopy(…) eignet sich dazu, sich vergrößernde Arrays zu implementieren, indem zunächst ein neues größeres Array angelegt wird und anschließend die alten Array-Inhalte in das neue Array kopiert werden.
auf dem gleichen Array: So lässt sich die Methode dazu verwenden, Elemente eines Arrays um bestimmte Positionen zu verschieben. Die Bereiche können sich durchaus überlappen.
[zB] Beispiel
Um zu zeigen, dass arraycopy(…) auch innerhalb des eigenen Arrays kopiert, sollen alle Elemente bis auf eines im Array f nach links und nach rechts bewegt werden:
System.arraycopy( f, 1, f, 0, f.length - 1 ); // links
System.arraycopy( f, 0, f, 1, f.length - 1 ); // rechts
Hier bleibt jedoch ein Element doppelt!
final class java.lang.System
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
Kopiert length Einträge des Arrays src ab der Position srcPos in ein Array dest ab der Stelle destPos. Der Typ des Arrays ist egal, es muss nur in beiden Fällen der gleiche Typ sein. Die Methode arbeitet für große Arrays schneller als eine eigene Kopierschleife.