PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : JAVA: Array zur Laufzeit vergrössern? Arraylist? dynamische Objektnamen??


derJavafragt
2004-05-06, 20:55:42
Hi, folgendes Problem:
Ich habe eine Anzahl von n elementen in einer Datei und jedes hat 3 eigenschaften. Die will ich irgendwie in Java repräsentieren.

Meine 1. Idee war ein mehrdimensionales array a la
array[n][0-2]
Problem ist das ich die Anzahl n erst weiss nachdem ich die Datei schon eingelesen habe. Müsste die datei also ein 2tes Mal einlesen & parsen was unschön ist und bei grossem n lange dauert.

2. Idee habe gelesen das ArrayList(); zur Laufzeit vergösserbar ist mittels .add();
Nur ist es möglich aus Arraylists etwas wie array[][] zu konstruieren?

3. Idee wäre natürlich super aus den Elementen gleich Objekte zu erstellen so das ich dann z.b. objekt1.eigenschaft1 usw. habe.
Das scheitert aber daran das man in Java wohl keine dynamischen Objektnamen benutzen kann, a la
["objekt"+i] = new Objekt; in Flash Actionscript z.b.


Irgendwer der sieht wo ich falsch liege und ob es eine gute Möglichkeit gibt das Problem zu lösen?

BubbleBoy
2004-05-06, 22:19:44
Java beherscht dyn. Arrays, wie wäre es damit?

HellHorse
2004-05-06, 22:50:40
Nee, Java kennt keine dynamischen Arrays, es gibt aber List's. Da Java kein Operator-Overloading unterstütz, kannst du auf die Elemente nicht per [] zugreiffen, sondern nur per get(). Du kannst aber jedes mögliche Objekt in eine Liste packen, also auch Listen selber, du brauchst dann allerdings zwei get's (und ein cast mit 1.4). Eins für die zweite Liste aus der ersten zu holen und eins um das Element aus der zweiten Liste zu holen.

Allerdings gibt gibt es Map's. Die erlauben dir, ein Objekt (z.B. ein String) auf ein anderes abzubilden.
du kannst dann
Object einObjekt = einMap.get("hallo");
machen. Du hast dann so etwas die "dynamische Objeknamen".

derJavafragt
2004-05-07, 01:57:44
Original geschrieben von HellHorse
Da Java kein Operator-Overloading unterstütz, kannst du auf die Elemente nicht per [] zugreiffen, sondern nur per get(). Du kannst aber jedes mögliche Objekt in eine Liste packen, also auch Listen selber, du brauchst dann allerdings zwei get's (und ein cast mit 1.4). Eins für die zweite Liste aus der ersten zu holen und eins um das Element aus der zweiten Liste zu holen.


Hi, danke für die Tipps!
Problem das ich dabei habe ist wenn ich eine Liste in eine Liste packe, da nur ein Verweis auf die Liste reinkommt und nicht die Liste selber.


arrayliste2.add("a"); //[0]="a"
arrayliste2.add("2"); //[1]="2"

arrayliste.add(arrayliste2); //[0]=arrayliste2
arrayliste.add(arrayliste2); //[1]=arrayliste2

System.out.println("Arraylist [0][0] vorher: "+ ((ArrayList) arrayliste.get(0)).get(0));
System.out.println("Arraylist [1][0] vorher: "+ ((ArrayList) arrayliste.get(1)).get(0));

((ArrayList) arrayliste.get(0)).add(0,"b");

System.out.println("Arraylist [0][0] nachher: "+ ((ArrayList) arrayliste.get(0)).get(0));
System.out.println("Arraylist [1][0] nachher: "+ ((ArrayList) arrayliste.get(1)).get(0));


Wenn ich z.b. den Wert in [0][0] ändere, ändert sich auch der Wert in [1][0].


Original geschrieben von HellHorse
Allerdings gibt gibt es Map's. Die erlauben dir, ein Objekt (z.B. ein String) auf ein anderes abzubilden.
du kannst dann
Object einObjekt = einMap.get("hallo");
machen. Du hast dann so etwas die "dynamische Objeknamen".



Die Methode hört sich komfortabel an, allerdings weiss ich nicht wie ich dann an die Variablen der Objekte lesen/ändern kann, denn .a findet er nicht mehr wenn ich mir das Objekt zurückholen will.


public static void main(String args[]){
test t = new test();

Map einMap=new HashMap();
einMap.put("hallo", t);

Object einObjekt = einMap.get("hallo");
System.out.println( (einObject.a);
}

static class test{
int a = 0;
}

mithrandir
2004-05-07, 07:51:52
Original geschrieben von derJavafragt
Problem das ich dabei habe ist wenn ich eine Liste in eine Liste packe, da nur ein Verweis auf die Liste reinkommt und nicht die Liste selber.
Hm... du addest ja zweimal dasselbe Objekt in deine arrayliste - das ist dir schon klar, oder?

Original geschrieben von derJavafragt
Die Methode hört sich komfortabel an, allerdings weiss ich nicht wie ich dann an die Variablen der Objekte lesen/ändern kann, denn .a findet er nicht mehr wenn ich mir das Objekt zurückholen will.
Das mag daran liegen, dass die get()-Methode lediglich eine Variable vom Typ Object zurückliefert. Du musst das Ergebnis auf jeden Fall casten (z.B. auf test).


Die Wahl der Klassen-/Variablennamen in deinen Beispielen ist übrigens nicht wirklich toll. Warum möchtest du das überhaupt in Java machen, wenn du von der Sprache gar keine Ahnung hast?

Ich würde einfach eine Klasse machen, die die drei Eigenschaften als Member-Variablen hat, evtl. sogar als Bean mit getter/setter-Methoden. Un die Objekte dieser Klasse kannst du ja in irgendeiner Collection ablegen (einer Map, wenn du über logische Namen zugreifen willst, eine ArrayList oder einen Vector, wenn du sequentiell darauf zugreifen möchtest.

Lies dir am besten auch mal das hier durch: http://java.sun.com/developer/onlineTraining/collections/Collection.html

bye, mith

derJavafragt
2004-05-07, 22:27:36
Das mag daran liegen, dass die get()-Methode lediglich eine Variable vom Typ Object zurückliefert. Du musst das Ergebnis auf jeden Fall casten (z.B. auf test).
[/SIZE]

Ok mittel casten kann ich den Wert lesen, hatte Hellhorse ja auch schon geschrieben, war nur zu dusselig das zu sehen.


Die Wahl der Klassen-/Variablennamen in deinen Beispielen ist übrigens nicht wirklich toll. Warum möchtest du das überhaupt in Java machen, wenn du von der Sprache gar keine Ahnung hast?
[/SIZE]

Wenn ich das könnte würde ich ja hier nicht fragen, werde dazu gezwungen es mit java zu machen ;D


Ich würde einfach eine Klasse machen, die die drei Eigenschaften als Member-Variablen hat, evtl. sogar als Bean mit getter/setter-Methoden. Un die Objekte dieser Klasse kannst du ja in irgendeiner Collection ablegen (einer Map, wenn du über logische Namen zugreifen willst, eine ArrayList oder einen Vector, wenn du sequentiell darauf zugreifen möchtest.
[/SIZE]

Ja mittles einer map kann ich ein Objekt über jeden Namen ansprechen den ich will, das löst aber nicht mein eigentliches Problem:

Ich muss eine Anzahl von n Objekten erschaffen, wobei ich n erst zur laufzeit erfahre.

einMap.put("element"+1, Element);

Wenn dabei jedesmal eine Kopie von Element unter "element"+1 gespeichert würde wäre ja alles in Ordnung.

Aber wenn ich mir z.b. "element"+1 hole und da eine Eigenschaft verändere überträgt sich das auf alle "element"+i, da nur ein Verweis auf das Objekt Element gespeichert wird.

Aqualon
2004-05-08, 09:54:39
Original geschrieben von derJavafragt
einMap.put("element"+1, Element);

Wenn dabei jedesmal eine Kopie von Element unter "element"+1 gespeichert würde wäre ja alles in Ordnung.

Aber wenn ich mir z.b. "element"+1 hole und da eine Eigenschaft verändere überträgt sich das auf alle "element"+i, da nur ein Verweis auf das Objekt Element gespeichert wird.
Das ist ja auch Sinn der Sache, dass nur Referenzen auf Objekte gespeichert werden. Um dein Problem zu lösen, musst du für jeden Eintrag in der Map die Referenz auf ein neues Objekt der Klasse Element speichern.

Aqua

HellHorse
2004-05-08, 11:18:12
Original geschrieben von derJavafragt
einMap.put("element"+1, Element);

Also wenn du als "dynamischer Objektname", bloss "element"+index verwendest, kannst du gleich eine List verwenden. Das ist wesentlich einfacher.
Original geschrieben von derJavafragt
Aber wenn ich mir z.b. "element"+1 hole und da eine Eigenschaft verändere überträgt sich das auf alle "element"+i, da nur ein Verweis auf das Objekt Element gespeichert wird.
Du holst eine Ojektreferenz aus einen Map, und ruft daran ein Methode auf. Die Folgen dieses Aufrufes werden vom Map nicht beeinflusst. Wenn die Methode bloss den Zustand des aktuellen Objektes ändert, dann ändert sich nur der Zustand des aktuellen Objektes. Wenn die Methode den Zustand aller Instanzen einer Klasse ändert, dann ändert sich Zustand aller Instanzen einer Klasse.

ethrandil
2004-05-08, 11:40:08
Also, ich machs mal schematisch für dich, okay?

class StartClass{
public static void main(String[] args){
List parsedObjects = new ArrayList();//Die Liste in der das geparste gespeichert wird

while(!isAtEndOfFile()){
String[] po_array = parseNext(); //Parst jeweils die nächsten drei attribute
ParsedObject po = new ParsedObject(po_array[0], po_array[1], po_array[2]); //Ein neues Objekt wird erzeugt
parsedObjects.add(po); //Objekt in die Liste einfügen
}
//Nun sind alle Objekte aus deiner Datei geparst!

for(int i=0; i<parsedObjects.size(); i++)
System.out.println("Object number "+i+" is:"+parsedObjects.get(i)); //Es kann nun per Index auf die Objekte zugegriffen werden
}
}

class ParsedObject{
private String attribute1, attribute2, atribute3;
public ParsedObject(String a1, String a2, String a3){
attribute1 = a1;
attribute2 = a2;
attribute3 = a3;
}
}


Ist das verständlich?

Du solltest aber die Klasse ParsedObject noch un die wichtigen Funktionen (zB. Getter) erweitern.

Außerdem wäre es schön, wenn parseNext(); gleich ein Objekt und nicht erst ein Array zurückgibt. Ansonsten solltest du noch die Datentypen anpassen, aber das schaffst du schon.

- Eth