ArrayList länge lässt sich nicht voreinstellen

Status
Nicht offen für weitere Antworten.

scaary

Bekanntes Mitglied
HI.

Ich habe ein Problemchen:
Code:
	private static int ALPHABET_LENGTH = 26;
	private ArrayList<Collection<Transition>> charAdj;

	State() {           
		charAdj = new ArrayList<Collection<Transition>>(ALPHABET_LENGTH+ 1) ; // + 1 Lambda
		
		System.out.println(charAdj.size());
	}
Als länge wird mir hier ständig 0 zurückgegeben, obwohl ich die Liste doch mit 27 Stellen erstelle.

Kann mir einer sagen, warum er mir hier nur eine Länge von 0 zurückgibt?

Danke!
 
Zuletzt bearbeitet:
Weil da noch nix drin ist. Du müsstest da erstmal einige Collection<Transition> reintun, dann liefert size(), wieviel drin sind. Das was du im Konstruktor übergibst, ist die initiale Kapazität. Deswegen sind da aber noch lange nicht soviel Elemente enthalten.
 
ahsoo.... d.h. der zeigt mir dann NUR an, was tatsächlich drin ist!


Das eklärt, warums ned geht 😛

Kann ich denn trotzdem z.B. auf die 5.te Stelle in der Liste zugreifen und da eine COllection einfuegen, ohne dass die ersten 4 Stellen Collections enthalten, oder muss ich alle erst vorinitialisieren?
 
Zuletzt bearbeitet:
Du kannst in einer List ein neues Objekt (bzw. in deinem Fall eine Collection) jeweils nur an Position 0 bis list.size() einfügen.
 
mhhh,das ist aber doof, warum ist dass denn dann eine arrayList wenn ich nicht auf weiterfüphrende Positionen zugreifen kann?
 
Wenn von einer Folge die Rede ist, gehe zumindest ich davon aus, dass, wenn es ein k-tes Element gibt, es auch ein k-1-tes Element gibt, das Vorgänger von k ist, oder kein solches k-1-tes Element, wenn k das erste Element ist. Oder anders gesagt: Es gibt kein zweites Mal ohne das erste Mal. 😉

Möglicherweise suchst du eine Map.

Ark
 
... ansonsten müßtest du die Liste mit 27 "default-Werten" füllen - also leere Listen, "null", dem 0-Character oder sonstwas...
 
Mhh, ich probiere jetzt die Liste mit folgender Methode zu füllen:

Code:
	private void fillList() {
		for(int i = 0; i < ALPHABET_LENGTH + 2 ; ++i) {
			Collection<Transition> col = null;
			charAdj.set(i, col);
		}
	}

aber erhalte ich folgende Exception:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(Unknown Source)
at java.util.ArrayList.set(Unknown Source)
at fa.State.fillList(State.java:40)
at fa.State.<init>(State.java:11)
at fa.NDA.initializeStates(NDA.java:64)
at fa.NDA.<init>(NDA.java:14)
at fa.Test.main(Test.java:9)

Ich versteh allerdings nicht, warum ich die exception kriege, immerhin hat die Liste ja 27 Stellen, und ich geh nicht über die 27 hinaus beim füllen...??
 
Zuletzt bearbeitet:
Wenn man sich den Code von ArrayList anschaut, sieht man, dass mit dem Konstruktor ArrayList(int capacity) zwar das interne Array mit dem Wert initialisiert wird, allerdings nicht das Attribut size. Dessen Wert ändert sich nur bei der Methode add().
Möchte man nun mit ArrayList.set(...) einen Wert einfügen, wird überprüft ob die gewünschte Position kleinergleich dem Wert von size ist. Wenn nicht, gibt es die IndexOutOfBounds.

Ein etwas seltsames Verhalten auf den ersten Blick. Allerdings muss man dabei bedenken, dass der Wert von size nur die tatsächlich enthaltenen (mit add hinzugefügten) Elemente wiedergeben soll und die initial capacity dazu dient, das interne Array bereits am Start auf die erwartete Größe zu bringen, dh. Speicher zu reservieren. Das Vergrößern von Arrays kostet bekanntlich einiges.

new ArrayList<String>(27) heisst also NICHT, dass bereits 27 Elemente enthalten sind
 
HI.
Danke für die schnelle Antwort.

OK, das initialisieren der 27 Nullzustände hab ich jetz endlich hinbekommen ^^

Jetzt hab ich nur das Problem beim Einfügen, dass ich eine Nullpointerexception erhalte, wenn ich ein Objekt zur Collection hinzufüge, da diese ja mit "null" initialisiert ist.

Wie umgeh ich jetzt das priblem?Gibt es hierfür einen alternativbefehl zu "add"?

Code:
for(int i = 0; iter.hasNext(); ++i) {
			if (i == position) {
				Collection<Transition> c = charAdj.get(position);
				if(c == null) {
					Collection<Transition> col = null;
					col.add(trans);
					charAdj.set(position, col);
				} else {
				c.add(trans);
				}
			}
		}

Exception in thread "main" java.lang.NullPointerException
at fa.State.addTransition(State.java:24)
at fa.NDA.addTransition(NDA.java:19)
at fa.Test.main(Test.java:11)
 
Dann überleg doch mal:
du "befüllst" die ArrayList mit null-Werten und versuchst dann, ein Element aus der Liste mit get auszulesen. Was glaubst du, was du in der Zeile
Java:
Collection<Transition> c = charAdj.get(position);
geliefert bekommst? Richtig, c = null. Daher auch die Nullpointer bei c.add().

EDIT:
Java:
if(c == null) {
	Collection<Transition> col = null;
	col.add(trans);
das ist, vereinfacht ausgedrückt, absolut sinnloser Code: zuerst überprüfst du auf null, wenn ja setzt du auf null und führst auf null eine Methode aus. Muss man da noch mehr zu sagen? 😉

Du musst erst eine Collection mit new erstellen (genauer gesagt eine Implementierung davon), dann darauf add() ausführen und zum Schluss charAdj.set(...)

Beispiel
Java:
Collection<Transition> c = new HashSet<Transition>();
c.add(new Transition());
charAdj.set(c, 4);
 
Zuletzt bearbeitet:
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben