Deep copy verschachtelter arrays machen?

bernd

Neues Mitglied
Hallom in meinem aktuellen "Projekt" kommt bspw. ein gebilde der Art
ArrayList<ArrayList<ArrayList<Long>>> vor.
Also als Menge geschrieben sowas wie {{{1,2}{3,4}}{{5,7}}}
sieht hässlich aus, ist es auch und ,acht wenig spaß damit zu arbeiten weil man höllisch aufpassen muss.

Nun bräuchte ich eine Kopie des ganzen auf der ich rumwerkeln kann.
Natürlich aber keine standardkopie, die nur referenzen kopiert, weil dann veränderungen an der kopie auch das original beeinflussen.

Insofern bräuchte ich da eine deep copy des Ganzen.

Gibts da einen shclaueren weg das hinzubekommen oder vielleicht einen passenden befehl?
Ich könnte nur von grund auf halt eine kopie nachbilden:
Java:
//Sei Array das alte arraylistgebilde
ArrayList<ArrayList<ArrayList<Long>>> copy = new ArrayList<ArrayList<ArrayList<Long>>>;

for (ArrayList<ArrayList<Long>> Arrayi : Array) {
  ArrayList<ArrayList<Long>> Copyi = new ArrayList<ArrayList<Long>>;

  for (ArrayList<Long> Arrayii : Arrayi) {
    ArrayList<Long> Copyii = new ArrayList<Long>;

    for (long a : Arrayii) {
      Copyii.add(a);
    }
    Copyi.add(Copyii);
  }
  Copy.add(Copyi);
}
//copy hat nun die selben inhalte wie array und das ohne referenzen


Das liest sich schlecht, lässt sich shcwer nachvollziehen (auch was vor, in oder nach der for schleife stehen muss)und noch schwieriger fehlen finden.
davon ab dass ich beid er Namensgebung nicht gut bin und daher probleme habe, sinnvolle namen für das zweitinnerste element oder so zu finden sodass man am schluss noch weiß was was ist wo rein gehört :-/

gibts das nicht irgendwie in einfacher oder so? :-/
 
Ich glaube selbst bei Java15 gibt es noch kein DeepCopy / DeepClone. Habe zumindest nix gefunden. ArrayLists implementieren zwar Cloneable und du könntest eine Schleife sparen. Aber schöner wirds dadurch nicht.


Spricht etwas dagegen, den primitiven Datentyp zu benutzen?
Also zum Beispiel long[][][] longJohnson = new long[3][5][2];

Beispiel zum Rumprobieren:
Java:
int lvl1 = 2, lvl2 = 2, lvl3 = 3; // Anzahl Elemente pro Ebene

// Hier String als Beispiel, um die Eingabe und Darstellung zu vereinfachen
String[][][] longJohnson = new String[lvl1][lvl2][lvl3];
for (int i = 0; i < lvl1; i++) {
  for (int j = 0; j < lvl2; j++) {
    for (int k = 0; k < lvl3; k++) {
      longJohnson[i][j][k] = String.format("(%d %d %d)", i, j, k);
    }
  }
}

System.out.printf("Original %d(%d(%d)):\n%s%n", lvl1, lvl2, lvl3, Arrays.deepToString(longJohnson));

// Wir tun so, als wüssten wir hier die Größe des Arrays nicht
int origLvl1 = longJohnson.length, origLvl2 = longJohnson[0].length, origLvl3 = longJohnson[0][0].length;
String[][][] cloneJohnson = new String[origLvl1][origLvl2][origLvl3];
for (int i = 0; i < origLvl1; i++) {
  for (int j = 0; j < origLvl2; j++) {
    cloneJohnson[i][j] = Arrays.copyOf(longJohnson[i][j], origLvl3);
  }
}

System.out.printf("Copy %d(%d(%d)):\n%s%n", cloneJohnson.length, cloneJohnson[0].length, cloneJohnson[0][0].length, Arrays.deepToString(cloneJohnson));

cloneJohnson[0][0][0] = "CHANGED!";

System.out.println("----");

System.out.printf("Original %d(%d(%d)):\n%s%n", lvl1, lvl2, lvl3, Arrays.deepToString(longJohnson));

System.out.printf("Copy %d(%d(%d)):\n%s%n", cloneJohnson.length, cloneJohnson[0].length, cloneJohnson[0][0].length, Arrays.deepToString(cloneJohnson));

Wenn du ein Objekt brauchst, dann würde ich das an deiner Stelle als eigene Datentyp machen und Clonable implementieren.

Wenn die Arraytiefe unterschiedlich groß ist, könntest du es rekursiv lösen.
 
Zurück
Oben Unten