# Asymmetrisches Array dynamisch erzeugen



## Shizzler (7. Jan 2008)

Hallo,

ich bin gerade dabei, ein API zu schreiben, das mir beliebige Objekte auf eine bestimmte Art in Dateien speichert und wieder ausliest.

Bei mehrdimensionalen Arrays habe ich da ein kleines Problem. Und zwar weiß ich nicht, wie man aus den Informationen, die einem beim Auslesen der Datei zur Verfügung stehen, wieder exakt das Ursprungsarray erzeugen kann.

Es gibt zwar eine statische Methode _newInstance_ in der Klasse _java.lang.reflect.Array_, diese kann allerdings scheinbar nur Arrays mit fest definierten Dimensionsgrößen erzeugen (zB. ein Array 3x2).

Beispiel:


```
package test;

import java.lang.reflect.Array;

public class Beispiel1 {
	public static final void main (String[] params) {
		String[][] ursprungsArray = new String[][] {
			{"eins", "zwei"},
			{"drei", "vier"},
			{"fünf", "sechs"}
		};

		// ... Arraygröße, Inhalt etc. aus einer Datei ermitteln
		int dims[] = new int[]{3, 2};

		// String Array mit der richtigen Größe erzeugen:
		Object oNew = Array.newInstance (String.class, dims);

		// ... Array füllen ...
	}
}
```

Was mir allerdings nicht gelingen will, ist ein Array mit asymmetrischer Größe zu rekonstruieren.

Beispiel:


```
package test;

public class Beispiel2 {
	public static final void main (String[] params) {
		String[][][] ursprungsArray = new String[][][] {
			{
				{"eins", "zwei"},
				{"drei", "vier", "fünf"},
				{"sechs"}
			},
			{
				{"sieben"},
				{"acht", "neun"}
			},
			{
				{"zehn", "elf", "zwölf", "dreizehn"}
			}
		};

		// ???
	}
}
```

Natürlich könnte ich die Maximale Größe ermitteln (3x3x4), aber das Ergebnis währe dann nicht mehr das Gleiche wie das ursprüngliche Objekt.

Auch will ich keine ArrayList, Vector o.ä. verwenden, es soll exakt das ursprüngliche Array herauskommen.

Kann mir da jemand weiterhelfen?

Danke im Voraus  :wink:


----------



## mhauert (7. Jan 2008)

Hallo!

Wenn ich dich richtig verstanden habe, willst du quasi ein Array von Arrays, wobei diese nicht alle die gleiche Größe haben...

IMHO ist das nur möglich wenn man in den Arrays ganz allgemein Variablen vom Typ Object speichert.

So inetwa könnte das aussehen:


```
public class arraytest {

	public static void main(String[] args)
	{
		Object[] first = new Object[2];
		Object[] second = new Object[2];
		Object[] third = new Object[1];
		first[0] = second;
		first[1] = third;
		((Object[])first[0])[0] = "0:0";
		((Object[])first[0])[1] = "0:1";
		((Object[])first[1])[0] = "1:0";
		System.out.println((((Object[])first[0])[0]+ " " + ((Object[])first[0])[1]+" "+ ((Object[])first[1])[0]));
	}
}
```

Natürlich ist das Parsing in dem Falle recht unübersichtlich, aber man kann sich ja eigene Klasse dieser Konstrukte anlegen.

Ich hoffe das konnte dir weiterhelfen.


----------



## Shizzler (7. Jan 2008)

Servus,

leider nein. Das Ergebis wäre vom Typ Object[][][] und nicht String[][][]. Das ist deswegen ein Problem, weil ich das nich der ursprünglichen Klasse zuordnen könnte.

Hier nochmal ein Beispiel. Ich habe ein Ursprungsobjekt vom Typ "_Datenklasse_". Dieses Objekt soll in einer Datei gespeichert werden (über ein eigenes Toolkit, nicht über Serialisierung) und später wieder ausgelesen werden.


```
FileToolkit ftk = ...
File file = new File ("testdatei.bin");
// Ein beliebiges Datenobjekt erzeugen
Datenklasse src = new Datenklasse ();
// Objekt "src" in Datei "file" speichern
ftk.save (src, file);
// Ein beliebiges Objekt vom Typ "Datenklasse" aus der Datei "file" lesen
Datenklasse res = (Datenklasse)ftk.load (file);
```

Die Klasse _Datenklasse_ könnte z.B. folgerndermaßen aussehen (ihr Aufbau soll aber möglichst keine Auswirkungen auf das Speichern / Laden haben):


```
public class Datenklasse {
	private String text;
	private int[][] vieleZahlen;

	public String getText() {
		return text;
	}
	public void setText(String text) {
		this.text = text;
	}
	public int[][] getVieleZahlen() {
		return vieleZahlen;
	}
	public void setVieleZahlen(int[][] vieleZahlen) {
		this.vieleZahlen = vieleZahlen;
	}
}
```

Wenn ich jetzt beim Auslesen der Datei ein Objekt der Klasse "Object[][]" erzeuge, bekomme ich Probleme beim Zuweisen auf das Array _vieleZahlen_. Ich muss das also irgendwie konvertieren. Andererseits mösste jede Datenklasse für ihre Arrays eine Möglichkeit bieten, ein Object Array einzulesen, was eine ziemlich unsaubere Lösung wäre.

Trotzdem Danke für deine schnelle Antwort.


----------



## Illuvatar (7. Jan 2008)

Hier mal ein Beispiel:


```
import java.lang.reflect.*;

public class ArrayReflectTest
{
  public static void main(String[] args)
  throws Exception
  {
    Object array = Array.newInstance(String[].class, 3);
    Object firstArray = Array.newInstance(String.class, 2);
    Object secondArray = Array.newInstance(String.class, 3);
    Object thirdArray = Array.newInstance(String.class, 1);
    
    Array.set(array, 0, firstArray);
    Array.set(array, 1, secondArray);
    Array.set(array, 2, thirdArray);
    
    Array.set(firstArray, 0, "Eins");
    Array.set(firstArray, 1, "Zwei");
    Array.set(secondArray, 0, "Drei");
    Array.set(secondArray, 1, "Vier");
    Array.set(secondArray, 2, "Fünf");
    Array.set(thirdArray, 0, "Sechs");
    
    print (array, 0);
    System.out.println(array.getClass());
  }
  private static void print (Object array, int depth)
  {
    if (array.getClass().isArray()){
      if (array.getClass().getComponentType().isArray()){
        System.out.println(tabs(depth) + "[");
        for (Object sub : (Object[])array){
          print (sub, depth + 1);
        }
      }else{
        System.out.print(tabs(depth) + "[");
        for (Object sub : (Object[])array){
          System.out.print (sub.toString() + " ");
        }
      }
      System.out.println("],");
    }else{
      System.out.println(tabs(depth) + array);
    }
  }
  private static String tabs (int depth)
  {
    StringBuilder ret = new StringBuilder();
    for (int i = 0; i < depth; i++){
      ret.append('\t');
    }
    return ret.toString();
  }
}
```

Die unteren beiden Methoden dienen nur der Ausgabe. Die Ausgabe lautet:

```
[
        [Eins Zwei ],
        [Drei Vier Fünf ],
        [Sechs ],
],
class [[Ljava.lang.String;
```


----------



## Shizzler (7. Jan 2008)

Vielen Dank  :toll:


----------

