# dynamische ArrayListen?



## Fry (11. Aug 2005)

Hallo!

Ich möchte nun folgendes machen:

- Datei aus dem Web per URL laden (ist eine Tabstop getrennte Datei)
- diese möchte ich in einer Datenstruktur speichern, und diese dann auswerten.

Randbedingungen:
- ich weiß nicht wieviele Zeilen und
- auch nicht wieviele Spalten es werden (obwohl Spalten zur Not noch fix zu setzen sind)

ich hätte gerne vom Prinzip sowas wie ein 2D Array ( werte[][] ). Da muss ich mich aber schon vorher festlegen wie groß es wird, was nicht möglich ist. (Und Definitionen wie werte[100][20000] pauschal sind nun eher schlecht ;-) )
Ich muss diese ganze Liste dann von oben nach unten durchsuchen und einzelne Felder prüfen. Also praktisch ist Feld [30][140] = "Ergebnis" oder größer als ein anderes Feld.
Die Einträge sind Zahlen und Strings. Die EInträge können locker in die 1000er gehen. Allerdings wird es keine laufzeitkritische Anwendung. Wenn die also halt irgendwo bspw. 5 Sek länger dauert, dann tuts das eben.

Dann dachte ich an ArrayListe, aber die gibts nicht mehrdimensional oder?
Welche Datenstruktur ist für sowas richtig geeignet?

Danke
Fry


----------



## Beni (11. Aug 2005)

Es gibt auch keine mehrdimensionalen Arrays, nur Arrays von Arrays :wink:

Genauso kannst du es mit den ArrayListen halten: verschachtle sie.

In Java 1.5-Code:

```
List<List<String>> matrix = new ArrayList<List<String>>();
matrix.add( new ArrayList<String>() );
matrix.get(0).add( "bla" );
System.out.println( matrix.get(0).get(0) );
```


----------



## byte (11. Aug 2005)

warum machst du dir nicht nen eigenen datentyp mit zwei feldern und speicherst die dann in ner liste deiner wahl?

objektorientiert halt ...


----------



## boskop (12. Aug 2005)

nee byto, ich glaube nicht, dass das objektorientierter als mit zwei ArrayListen geht (Wenn das ganze noch Platz spaaren soll).

Bei deiner Variante hättest du wohl pro Node ein Object, aber enorme Redundanz, wenn ich das richtig verstanden habe.


----------



## Sky (12. Aug 2005)

Also, generische Programmierung (...es können Zahlen und Strings sein...) ist immer relativ "teuer"; sowohl in der Entwicklung also auch in der Laufzeit (Performance).

Wenn Du die Struktur vorher festlegen könntest (also bspw. Spalten 1-3 immer Zahlen; Spalten 4-7 Strings usw.) und das ganze in Objekte packen würdest könntest Du relavtiv einfach Methoden zur Auswertung (z.B. um Eigenschaften zu addieren oder zu vergleichen oder oder oder) schreiben, weil deine Objekte immer gleich aussehen...

btw.: bei der Lösung mit den ArrayListen hast Du nicht zwei Arraylisten, sondern Du hast eine für die Zeilen und pro Zeile eine für die Spalten.


----------



## boskop (12. Aug 2005)

Ja das mit den 2 ArrayListen war natürlich Quatsch, klar sind es Anzahl Spalten + 1.

Aber wenn ja die Datei beim Lesen fertig geschrieben ist, sprich sich nicht mehr ändert, wenn du sie in die Datenstruktur speichern willt, kannst du das ganze ja auch in einem Array mit nur einer Dimension speichern (Grösse= Zeilen * Spalten). Beim hineinspeichern gehst du einfach Zeile für Zeile. 
Bei einer 3x3 Tabelle wird dann quasi so ins Array gespeicher: [Zeile 1/Spalte 1; 1/2; 1/3; 2/1; 2/2;... ] 

Beim herauslesen musst du dann etwas herumrechnen mit Modulo und so, aber die richtige position lässt sich da schnell finden.


----------



## boskop (12. Aug 2005)

mhh... Moment mal... dann könntest du ja von Anfang an ein 2-dimensionales Array nehmen...?

Kannst du denn nicht vorher schauen, wie gross(Zeilen/Spalten) die Datei ist?


----------



## Fry (12. Aug 2005)

Hallo!

erstmal schönen Dank für die vielen Antworten. Prinzipiell kann man natürlich auch die Zeilen und Spalten bestimmten. Wie macht man das am besten?
Meine Idee ist:

- URL bestimmten und per openConnection() InputStream holen
- InputStream mit BufferedReader lesen
- Solange BufferedReader Objekt nicht "null" nächste Zeile lesen (in dieser Schleife könnte man einen Zähler für die Zeile hochzählen lassen).
- Die Spalten könnte man z.B. mit einem StrinkTokenizer ( Delimiter auf \t setzen) zählen. Die Anzahl der Zeilen ist in jeder Spalte gleich! (Man brauch also nur eine Spalte zu zählen)

Ich würde dann das BufferedReader Objekt einmal zum durchzählen verwenden, und danach zum Array[][] füllen, dass ich dann mit den durchgezählten Zeilen und Spalten initialisiere.

So richtig und gut?
Fry


----------



## messi (12. Aug 2005)

Nimm für die Zeilen eine ArrayList, weil die nichts anderes ist als ein Wrapper für Object[], der nach Bedarf ein größeres Object[] erstellt und dann kopiert. Und für die Spalten-Werte in jeder Zeile nimmst du direkt ein Object[].


```
BufferedReader reader = new BufferedReader(...);
ArrayList<String[]> zeilen = new ArrayList<String[]>(10000);
String zeile = reader.readLine();
while (zeile != null) {
  String[] werte = zeile.split("\t");
  zeilen.add(werte);
  zeile = reader.readLine();
}
reader.close();
```
(Nicht getestet.)

Wenn du unbedingt mit StringTokenizer arbeiten willst, dann speicherst du die Tokens zuerst in eine ArrayList und holst dann das Object[] mit ArrayList.toArray(). Diese ArrayList kannst du dann .clear() löschen und für die nächste Zeile wiederverwenden.


----------

