Collections Array mit generischen Typ

hansmueller

Bekanntes Mitglied
Hallo,

die Arrayerzeugung ist eigendlich ganz einfach:
Java:
Ding[] dingsda = new Ding[200]
Für ein mehrdimensionales Array hängt man einfach nur ein paar eckige Klammern zusätzlich dran.

Nur bei folgenden Fall funktioniert das nicht:
Ich hatte gerne ein mehrdimensionales Array mit einer ArrayList<String> als Typ.
Wenn ich es so schreibe, gibt mir Eclipse einen Fehler an:
Java:
ArrayList<String>[][] alDaten = new ArrayList<String>[10][11];
"Cannot create a generic array of ArrayList<String>" ist dieser Fehlerhinweis.

Wenn ich es so schreibe, gibt mir Eclipse nur noch eine Warnung:
Java:
ArrayList<String>[][] alDaten = new ArrayList[10][11];
"Type safety: The expression of type ArrayList[][] needs unchecked conversion to conform to ArrayList<String>[][]"

Wieso funktioniert die erste Schreibweise nicht? Formal müßte sie ja richtig sein.
Die zweite Schreibweise funktioniert zwar, aber was soll ich von diesen Warnhinweis halten? Und welche Auswirkungen könnte dies nach sich ziehen?
Ist das eine Besonderheit, die es bei diesen Generics bzw. Collections gibt?

MfG
hansmueller
 
Zuletzt bearbeitet von einem Moderator:
ausprobieren ausprobieren, früher war sowas noch verbreitet, mit Mehrdimensionalität hat das doch überhaupt nichts zu tun,
wenn du
Java:
ArrayList<String>[] alDaten = new ArrayList<String>[10];
schreibst bzw. das andere auch nur mit einer Dimension, dann hast du exakt dasselbe...
ich passe den Titel an, entferne die Mehrdimensionalität

ansonsten ist nur zu sagen, dass Java Arrays + Generics leider nicht gut kombinieren kann,
die erste Variante ist schlicht verboten, die andere nicht gefährlicher als
Java:
ArrayList<String> al = new ArrayList();
mit derselben Warnung,
Probleme kann es da nicht geben direkt bei Objekterstellung
 
SlaterB hat gesagt.:
... mit Mehrdimensionalität hat das doch überhaupt nichts zu tun ...
Jup, das war mir schon klar (ich habe es ausprobiert), habe aber gerade den Fall, daß ich es eben gleich mehrdimensional brauche. Werde das nächste mal bei einer solchen Frage versuchen, das Problem auf den kleinsten Nenner zu kürzen.

Es geht mir eigendlich mehr um das Verständnis. Warum lassen sich Java Arrays + Generics nicht gut kombinieren? Warum ist die erste Variante verboten? Und die Warnung bei der zweiten Variante wird ja wohl nicht zum Spaß ausgegeben?

MfG
hansmueller
 
warum kann nicht wirklich beantworten, vielleicht hat jemands anders eine Kurzfassung, ansonsten lange Texte durchsuchen
Internet-Suche 'java generics arrays' führte soeben recht schnell zu

AngelikaLanger.com - Java Generics - Type Erasure - Angelika Langer Training/Consulting
2 Einschränkungen für Parametrisierte Typen
[..]
* Arrays. Ein parametrisierter Typ ist als Elementtyp eines Arrays nicht zugelassen. Das heißt, es darf zum Beispiel kein Array des Typs Comparable<String>[] deklariert oder erzeugt werden. Die einzige Ausnahme ist die Wildcard-Instanziierung des parametrisierten Types: eine Deklaration wie Comparable<?>[] ist erlaubt. Das Verbot parametrisierter Typen als Elementtyp eines Arrays ist zunächst einmal eine recht überraschende Einschränkung, die sich der Praxis dann auch als reichlich lästig erweist. Sehen wir uns die Hintergründe genauer an. Die Ursache der Einschränkung liegt wieder in der Type Erasure.
[..]
2.1 Keine parametrisierten Typen als Array-Elemente
[..]
2.2 Die Folgen ignorierter Warnungen [das interessiert dich ja anscheinend auch besonders 😉 ]
 
Danke für den Link SlaterB.
Ist ein interessanter Artikel. Zwar keine leichte Lektüre aber mir ist die Sache jetzt schon etwas klarer.

Wenn ich es richtig verstanden habe, sollte ich mit
Java:
ArrayList<String>[][] alDaten = new ArrayList[10][11];
keine Probleme bekommen, solange ich nicht irgendwelche cast-Geschichten mache, um mit aller Gewalt dort eine ArrayList reinzudrücken.

Wenn keine weiteren Beiträge folgen, markiere ich heute Abend dieses Thema als erledigt.

MfG
hansmueller
 
Warum verwendest du überhaupt ein zweidimensionales Array einer ArrayList? Also eigentlich eine dreidimensionale Datenstruktur. Du könntest auch Listen ineinanderschachteln, also List<List<List<String>>>, dann wärst du von der Typsicherheit her jedenfalls auf der sicheren Seite.
 
@andiv: Die Idee hatte ich auch schon 🙂, trotzdem danke für den Vorschlag.
Java:
		ArrayList<ArrayList<ArrayList<String>>> alDatenA = new ArrayList<ArrayList<ArrayList<String>>>();
		ArrayList<String> x = alDatenA.get(0).get(0);
		
		//versus
		
		ArrayList<String>[][] alDatenB = new ArrayList[10][11];
		ArrayList<String> y = alDatenB[0][0];

Ich wette, daß die verschachtelten Listen mehr Speicher und Rechengeschwindigkeit benötigen als das Array. Dem gegenüber steht die Typsicherheit und ein paar nützliche Methoden.

Da mein Programm, für das ich diese Datenstruktur brauche jetzt schon ganz schön am rechnen und speicherfressen ist, werde ich mich wohl für das Array entscheiden.

MfG
hansmueller
 
Mehrdimensionale Arrays betrachte ich immer skeptisch. Es ist nun mal schwer verständlich was sie machen sollen und bei
Code:
a.get(x).get(y).get(z)
oder
Code:
a[x][y][z]
ist es schwer zu erkennen was da eigentlich zurückkommt.
Wie befüllst du die Arrays denn? Von der Platte mit vordefinierten Werten oder dynamisch zur Laufzeit? Bei ersterem können mehrdimensionale Arrays sinnvoll sein, z.B. als statische Map für einen Wert mit einem Schlüssel dazu. Mehr als ein zweidimensionales Array hab ich aber noch nie gebraucht. Dafür dürfte Objektorientierung dann sinnvoller sein. Bei letzterem ist es immer fraglich ob statische Arrays so sinnvoll sind, z.B. beim Speicherplatz von Array vs. ArrayList wäre ich mir nicht so sicher. Ein
Code:
a[10][10][10]
verbraucht 10 * 10 * 10 Einheiten Speicherplatz, eine verschachtelte ArrayList hingegen kann viel weniger verbrauchen wenn nicht alle Elemente gefüllt werden.

Schon mal über ein bisschen Objektorientierung nachgedacht?
Code:
class Vector { int x,y,z }
ist meist verständlicher und man hat nur ein Array, das alle Vektoren beinhaltet.
 
@Antoras: Dein Beispiel mit den Vector kann ich leider nicht ganz nachvollziehen.

Meinst du etwa, daß ich eine Klasse schreiben soll, in der die Werte "Spalte x", "Zeile y" und die "ArrayList<String> alDaten" gespeichert werden und dann die Objekte dieser Klasse in einen Array packen soll?
Wäre auch eine Lösung, aber die Suche nach einen Eintrag in diesem Array ist bestimmt nicht die Schnellste.

MfG
hansmueller
 
Der Overhead durch die Objektorientierung ist vernachlässigbar wenn der Suchalgorithmus Müll ist. Will sagen: Hast du dir Gedanken darüber gemacht ob man den Suchalgorithmus verbessern könnte? Denn wenn nicht bringt es auch nichts sich Gedanken über ein paar Mikrooptimierungen zu machen und dadurch dann vllt. Code-Obfuskierungen in Kauf zu nehmen.
 
@Antoras: Ist ein bißchen viel Aufwand, einen eigenen ausgefeilten Suchalgorithmus zu schreiben.
Da verwende ich doch lieber bereits bestehenden Code in Form von mehrdimensionalen Arrays oder verschachtelten Listen (Auch ein Aspekt der OOP).
Und im Endeffekt ist es mit der Verständlichkeit auch nicht weit her.
Ob ich jetzt
Code:
ArrayList<String> a = alDatenLagerA.get(x).get(y);
,
Code:
ArrayList<String> b = alDatenLagerB[x][y];
oder
Code:
ArrayList<String> c = alDatenLagerC.getListe(x,y);
schreibe, ist ja wohl wirklich nicht der große Unterschied.

MfG
hansmueller
 
In der Objektorientierung kommt es in erster Linie nicht darauf an Daten miteinander zu gruppieren, sondern deren Abhängigkeiten zueinander zu analysieren und eine geeignete Datenstruktur darauf zu entwickeln. Bei einem
Code:
alDatenLagerC.getListe(x,y)
hättest du tatsächlich wenig gewonnen, aber vllt. gibt es ja die Möglichkeit diese Daten im voraus zu gruppieren, geschickt miteinander zu kombinieren und so eine geeignete Struktur zu finden.

Da kann ich dir leider nicht weiter helfen, da ich nicht weiß was du da für Daten hast und was du mit ihnen machen musst. Diese Analyse erfordert im übrigen eine gewisse Erfahrung und natürlich einen vllt. nicht unerheblichen Zeitaufwand. Mit Suchalgorithmus meine ich im übrigen nicht, dass du den selbst implementieren sollst, sondern dass du auf vorgefertigte Datenstrukturen zurückgreifst um die Daten einfacher und vor allem effizient wiederfinden zu können. Eine Suche in einer Liste/einem Array ist z.B. sehr teuer, eine Map oder ein Set ermöglichen hier Wunder und zwar ohne, dass du wissen musst wie sie funktionieren. Dafür sind sequentielle Datenstrukturen besser für ein Iterieren über deren Elemente geeignet.

Das Wissen welche Datenstruktur wo sinnvoll ist gehört zum Grundwissen jedes Programmierers und du wirst nicht drumherum kommen es dir anzueignen.
 

Zurück
Oben