Methoden clone(), arraycopy(): ein- und zweidimensionale Arrays

Javinner

Top Contributor
Java ist auch eine Insel hat gesagt.:
Wollen wir eine Kopie eines Arrays mit gleicher Größe und gleichem Elementtyp schaffen, so nutzen wir dazu die Objektmethode clone(). Sie klont – in unserem Fall kopiert – die Elemente des Array-Objekts in ein neues.
Mir ist beim experimentieren etwas aufgefallen:
Java:
package arrays;

public class Arrays
{

    public static void main(String[] args)
    {
        int[][] zweidimensional = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

        int[] eindimensional = {1, 2, 3, 4, 5, 6, 7, 8, 9};

        System.out.println("--------------------------Ausgangssituation"
                + "\n");
        druckeZweidimensional(zweidimensional);
        druckeEindimensional(eindimensional);

        System.out.println("--------------------------Testversuch: Eindimensional.clone()"
                + "\n");

        /**
         * Beim Verweis auf ein Array wird im Fall einer Aenderung im
         * Verweisarray der Wert an Ort und Stelle im "Originalarray" ebenso
         * geaendert. Erst bei einer Kopie, welche mit array.clone() erstellt
         * wurde, kann von eigenstaendigen Array ausgegangen werden.
         *
         * a) Auf das Original-Array zeigen nun zwei Variablen; 
         * b) Ein eigenstaendiges Array wird mit array.clone() erstellt 
         * c) Die zweite Variable des Original-Arrays wird geaendert, sprich das
         * Original-Array ebenso
         *
         * Wie auch in diesem Beispiel funktioniert alles so wie beschrieben,
         * bei Original- und Verweis-Array wird die erste Indexvariable
         * geaendert.
         */
        //a
        int[] verweisAufEindimensional = eindimensional;
        //b
        int[] kopieEindimensional = eindimensional.clone();
        //c
        verweisAufEindimensional[0] = 100;

        druckeEindimensional(eindimensional);
        druckeEindimensional(verweisAufEindimensional);
        druckeEindimensional(kopieEindimensional);
        
        System.out.println("--------------------------Testversuch: Eindimensional System.arraycopy"
                + "\n");
        
        int[] eindimens = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        int[] eindimensA = eindimens;
        int[] eindimensB = eindimens;
        System.arraycopy(eindimens, 0, eindimensB, 0, eindimens.length);
        eindimensA[0] = 100;
        druckeEindimensional(eindimens);
        druckeEindimensional(eindimensA);
        druckeEindimensional(eindimensB);

        System.out.println("--------------------------Testversuch: Zweidimensional.clone()"
                + "\n");

        /**
         * eben die gleiche Vorgehensweise wende ich auf ein zweidimensionales
         * Array an, jedoch ist das Ergebnis ein anderes. der Wert wird in allen
         * Arrays geaendert.
         */
        int[][] verweisAufZweidimensional = zweidimensional;
        int[][] kopieZweidimensional = zweidimensional.clone();
        verweisAufZweidimensional[0][0] = 100;

        druckeZweidimensional(zweidimensional);
        druckeZweidimensional(verweisAufZweidimensional);
        druckeZweidimensional(kopieZweidimensional);

        System.out.println("--------------------------Testversuch: Eigene Methode"
                + "\n");

        //
        int[][] test = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

        int[][] testA = test;
        int[][] testB = arraycopy(test);
        testA[0][0] = 100;
        druckeZweidimensional(test);
        druckeZweidimensional(testA);
        druckeZweidimensional(testB);
        
        
        System.out.println("--------------------------Testversuch: Zweidimensional System.arraycopy"
                + "\n");
        
        int[][] systemMethodeArrayCopy = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        int[][] systemA = systemMethodeArrayCopy;
        int[][] systemB = systemMethodeArrayCopy;
        System.arraycopy(systemMethodeArrayCopy, 0, systemB, 0, systemMethodeArrayCopy.length);
        systemA[0][0] = 100;
        druckeZweidimensional(systemMethodeArrayCopy);
        druckeZweidimensional(systemA);
        druckeZweidimensional(systemB);
        

    }

    static void druckeZweidimensional(int[][] array)
    {
        System.out.println("Zweidimensional");
        for (int x = 0; x < array.length; x++) {
            for (int y = 0; y < array[x].length; y++) {
                if (y < array[y].length - 1) {
                    System.out.print(array[x][y] + ", ");
                } else {
                    System.out.print(array[x][y]);
                }
            }
            System.out.println();
        }
    }

    static void druckeEindimensional(int[] array)
    {
        System.out.println("Eindimensional");
        for (int i = 0; i < array.length; i++) {
            if (i < array.length - 1) {
                System.out.print(array[i] + ", ");
            } else {
                System.out.print(array[i]);
            }
        }
        System.out.println();
    }

    static int[][] arraycopy(int[][] array)
    {
        int[][] uebergabe = new int[array.length][array[0].length];
        for (int x = 0; x < array.length; x++) {
            for (int y = 0; y < array[x].length; y++) {
                uebergabe[x][y] = array[x][y];
            }
        }
        return uebergabe;
    }

}
//Konsolenausgabe
--------------------------Ausgangssituation

Zweidimensional
1, 2, 3
4, 5, 6
7, 8, 9
Eindimensional
1, 2, 3, 4, 5, 6, 7, 8, 9
--------------------------Testversuch: Eindimensional.clone()

Eindimensional
100, 2, 3, 4, 5, 6, 7, 8, 9
Eindimensional
100, 2, 3, 4, 5, 6, 7, 8, 9
Eindimensional
1, 2, 3, 4, 5, 6, 7, 8, 9
--------------------------Testversuch: Eindimensional System.arraycopy

Eindimensional
100, 2, 3, 4, 5, 6, 7, 8, 9
Eindimensional
100, 2, 3, 4, 5, 6, 7, 8, 9
Eindimensional
100, 2, 3, 4, 5, 6, 7, 8, 9
--------------------------Testversuch: Zweidimensional.clone()

Zweidimensional
100, 2, 3
4, 5, 6
7, 8, 9
Zweidimensional
100, 2, 3
4, 5, 6
7, 8, 9
Zweidimensional
100, 2, 3
4, 5, 6
7, 8, 9
--------------------------Testversuch: Eigene Methode

Zweidimensional
100, 2, 3
4, 5, 6
7, 8, 9
Zweidimensional
100, 2, 3
4, 5, 6
7, 8, 9
Zweidimensional
1, 2, 3
4, 5, 6
7, 8, 9
--------------------------Testversuch: Zweidimensional System.arraycopy

Zweidimensional
100, 2, 3
4, 5, 6
7, 8, 9
Zweidimensional
100, 2, 3
4, 5, 6
7, 8, 9
Zweidimensional
100, 2, 3
4, 5, 6
7, 8, 9
Erfolge eindimensional: nur clone()
Erfolge zweidimensional: nur eigene Methode

Warum erstellt weder die clone() noch arraycopy()
eine eigenständige Kopie eines zweidimensionalen Arrays?
 
X

Xyz1

Gast
clone() ist evil, ich vermute zur Abwechslung mal, es wird nur eine flache Kopie erstellt.
 

Javinner

Top Contributor
@DerWissende
Java ist auch eine Insel hat gesagt.:
3.8.17 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().21 Sie klont – in unserem Fall kopiert – die Elemente des Array-Objekts in ein neues. 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
Was ist eine flache Kopie? Was wäre die erste Dimension?
int[][] array = new int[ erste Dimension? ][]
Stehe total auf dem Schlauch..
 

Robat

Top Contributor
Wenn du von einem 2D-Array eine "flach"-Kopie bekommst, dann wird nur die äußere Dimension kopiert. Die inneren Dimensionen beider Arrays zeigen auf die gleichen Adressen.
Das hat zufolge, dass Änderungen in einem Array beide betreffen, da wie gesagt die Adressen gleich sind.
 

Javinner

Top Contributor
@Robat
x = äußere Dimension
Ist es so richtig?
Java:
package testarray;

public class TestArray
{

    public static void main(String[] args)
    {
        int[][] flacheKopie = new int[10][10];
       
        abbildeKopie(flacheKopie);
    }

    static void abbildeKopie(int[][] array)
    {
        for (int x = 0; x < array.length; x++) {
            for (int y = 0; y < array[x].length; y++) {
                if (x == 0) {
                    System.out.print("x ");
                } else if (x > 0 && x < array.length - 1) {
                    if (y == 0 || y == array[x].length - 1) {
                        System.out.print("x ");
                    } else {
                        System.out.print(". ");
                    }
                } else if (x == array.length - 1) {
                    System.out.print("x ");
                }
            }
            System.out.println();
        }
    }

}

Konsolenausgabe:
x x x x x x x x x x
x . . . . . . . . x
x . . . . . . . . x
x . . . . . . . . x
x . . . . . . . . x
x . . . . . . . . x
x . . . . . . . . x
x . . . . . . . . x
x . . . . . . . . x
x x x x x x x x x x
 

Robat

Top Contributor
Ehm nein nicht wirklich.
Ein 2D-Array ist ja im Prinzip nichts anderes als ein Array von Arrays.

Java:
int[][] arr = new int[2][5];
int outerDim0[] = arr[0];  // liefet ein neues Array
int outerDim1[] = arr[1];  // liefert ein neues Array

int[][] arr2 = new int[2][5];
System.arraycopy(arr, 0, arr2, 0, arr.length);

Wenn du jetzt auf ein 2D-Array System.arraycopy oder clone anwendest dann wird zwar die äußere Dimension, welche die inneren Arrays beinhaltet, ordnungsgemäß kopiert aber die inneren Arrays nicht.
arr[0] und arr[1] wären also in deinem neuen Array genau die gleichen und würden die Änderungen auf beide Arrays übertragen.
 

Javinner

Top Contributor
@Robat
Habe jetzt in der Insel und im Netz nachgeschaut. Der Unterschied zwischen Flach- und Tiefkopie besteht wohl darin, dass bei einer flachen Kopie letztendlich nur eine neue Variable erzeugt wird, welche auf das "Mutter"-Array zeigt und, wenn man hier eine Indexvariable ändert, ändert man diese auch in "Mutter"-Array.
Bei einer tiefen Kopie wird ein neues und eigenständiges Array mit kopierten Werten und dessen Werten erzeugt.
Standardmäßig bittet Java hier wohl nichts an, so dass man hier selbst fallbezogen Programmieren muss.

Wundert mich trotzdem, denn in dem eindimensionalen Array ja die clone() Methode zum gewünschten Ergebnis führte.. Hm..
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A deepcopy mit clone() Allgemeine Java-Themen 2
R Gleiche Objektreferenz trotz clone()? Allgemeine Java-Themen 12
P Unterschiedliche Clone- Methoden Allgemeine Java-Themen 5
H Frage zu clone() Allgemeine Java-Themen 5
xehpuk clone() wegen leerem Cloneable quasi nutzlos? Allgemeine Java-Themen 6
M Überschreiben der clone()-Methode Allgemeine Java-Themen 10
G Object mit clone kopieren Allgemeine Java-Themen 21
R Eigenes Objekt - clone() Allgemeine Java-Themen 2
V clone() ? Allgemeine Java-Themen 4
T abstract + clone() = BUMM! Allgemeine Java-Themen 3
J immutable HashMaps und clone() Allgemeine Java-Themen 3
M Gibt es eigentlich einen Standalone-Java-ICQ-clone Allgemeine Java-Themen 19
M clone-methode nicht verfügbar Allgemeine Java-Themen 10
0 Keine clone-Methode für BigDecimal und BigInteger? Allgemeine Java-Themen 3
M Problem mit Generics und clone() Allgemeine Java-Themen 2
K The method clone() from the type Object is not visible. Allgemeine Java-Themen 9
D System.arraycopy verhält sich seltsam Allgemeine Java-Themen 1
J System.arraycopy ergibt anderes Resultat als for-loop Allgemeine Java-Themen 4
S Best Practice System.arrayCopy verändert Ziel-Array Allgemeine Java-Themen 2
H Interpreter-Fehler ArrayIndexOutOfBoundsException bei System.arraycopy() Allgemeine Java-Themen 3
W Konflikt byte->int, in.read->arraycopy Allgemeine Java-Themen 7
I arraycopy und tiefes Klonen Allgemeine Java-Themen 3
H Zweidimensionale Arrays Allgemeine Java-Themen 6
C Zweidimensionale Arrays - Quadratisch? Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben