Java Generic Arrays?

ascer

Captain
Registriert
Juni 2008
Beiträge
3.855
Huhu Leute,



ich hab jetzt schon eine Weile gesucht, aber leider ist mir der Sachverhalt trotzdem noch nicht klar geworden.
Warum kann man keine generic arrays in Java erzeugen?

Und warum kann man keine Arrays von Containern erzeugen, die bestimmte Elemente enthalten, z.B. ein Array von LinkedLists<E>?

Also sowas hier:

Code:
LinkedList<SomeType>[] array = new LinkedList<SomeType>[initial_size]

Ich bin jetzt dazu übergegangen einfach @SupressWarnings("unchecked") für mein Array zu nutzen und es so zu implementieren:

Code:
LinkedList<SomeType>[] array = new LinkedList[initial_size]

Ist wahrscheinlich nicht gerade die schönste Variante, oder?

Mein Problem dabei ist folgendes: ich bekomme halt mehrere Listen auf einmal die ich in einem Array sammeln will. Jedes Mal, wenn das passiert, haben die Listen aber nicht immer unbedingt die gleiche Wrapper-Klasse. D.h. einmal gibts halt 10 Listen LinkedList<SomeType> und später vielleicht mal 8 Listen LinkedList<AnotherType>...

Gibt dafür einen besseren Weg, dass zu lösen?
(Ich weiß vorher nicht, was für einen Typ die Listen haben, die ich bekomme, das hängt vom User ab)



Grüße & Danke im schon mal voraus

ascer
 
Hm, hast du vielleicht nachgedacht Manuals für LinkedList durchzulesen?

Was genau willst du mit generischen Listen machen?
Code:
LinkedList<SomeType> array = new LinkedList<SomeType>();
array.add(new SomeType());

Ist hier auch beschrieben.

Was du vorhin gemacht hast ist:
Einen LinkedList Array zu erzeugen.
Wenn du nur array brauchst kannst du direkt
Code:
SomeType[] array = new SomeType[x];
erzeugen.

Aber wie ich verstehe brauchst du entweder 2-dim Array
Code:
SomeType[][] array = new SomeType[x][y];
oder du kannst es als LinkedList erstellen:
Code:
LinkedList<SomeType[]> array = new LinkedList<SomeType[]>();
array.add(new SomeType[2]);

oder auch
Code:
LinkedList<LinkedList<SomeType>> array = new LinkedList<LinkedList<SomeType>>();
array.add(new LinkedList<SomeType>());
 
Können SomeType und AnotherType kein gemeinsames Interface haben? Wenn sie völlig unterschiedlich sind, frage ich mich, warum du sie an der gleichen Stelle "bekommst". Schwer zu beurteilen ohne zu wissen, was du da treibst.

Warum nicht einfach eine Liste von Listen? Wenn du so an Arrays hängst, haben Collections auch eine toArray-Methode, die du benutzen kannst.
 
Arrays deshalb, weil es mitunter viele Listen sind und ich eine relativ gute Hashfunktion dafür habe, man will ja nicht zu viel Performance verschenken ;)

Arrays wollte ich nicht komplett nehmen, weil ich bekomme halt schon fertige sortierte Listen, klar könnte man die noch umwandeln, aber ich tue da eh nichts anderes als die später mal zu iterieren und auf allen Elementen verschiedene Sachen aufzurufen. Deshalb erschien es mir am sinnvollsten, die Datenstruktur einfach beizubehalten.

@Tumbleweed:
Vielen Dank für die Idee mit dem Interface, die ist klasse :)
Hab den Wald mal wieder vor lauter Bäumen nicht gesehen ;)

@roker002:
Vielen Dank für den Tutorial-Link, einiges davon ist mir zwar schon bekannt, anderes aber auch nicht und es ist schön und verständlich zusammengefasst :)

Auch vielen Dank für deine Zusammenfassung, welche Möglichkeiten es alle gibt.

Und ja, ich brauche eine zweidimensionale Datenstruktur und wollte diese als Array von LinkedLists anlegen, weil die Listen, die ich bekomme, eben schon fertig zum "Gebrauch" sind und das Array soll sie mir einfach nur alle halten. Warum ein Array? Wie gesagt, ich hab eine relativ vernünftige Hashfunktion, die mir für die Listen hashes errechnet, sodass ich sehr fix nachgucken kann, welche Liste wo im Array ist.


Ich lese ferner heraus, dass es keine direkte Möglichkeit gibt sowas zu machen:

Code:
LinkedList<SomeType>[] array = new LinkedList<SomeType>[initial_size]
?!
 
Right. Muss sagen, dass mir das bisher auch nicht bewusst war. Ich hatte irgendwie nie das Bedürfnis, das zu versuchen. Wenn der Performance-Unterschied zwischen einer ArrayList und einem Array der Flaschenhals deiner Anwendung ist, dann hast du alles richtig gemacht. Ansonsten riecht es nach premature optimization. First make it run(, then profile it), then make it fast.
 
In der Tat, die "premature optimization" sollte ich vielleicht wirklich erstmal vergessen...man könnte schon sagen, dass die Anwendung aktuell eher Alpha-Status hat ;)

Vielen Dank für die Antworten :)
 
also bei 1 mio datensätze würde ich schon auf die Performance achten. Aber wenn es sich um max 1.000 Datensätze handelt, dann bringt diese Optimierung wenig was.
 
Es ist zudem egal, welchen Generischen Typ du wählst.

Was ich damit meine ist:

LinkedList<Typ>[] = LinkedList<Object>[]. Die Erklärung dafür ist ein wenig heikel. So weit ich weiß hat das mit der Abwärtskompatiblität von der JRE zu tun.

Du kannst aber auch Whitecards verwenden:

ArrayList<LinkedList<? : Deine Klasse>> bezeichner;
 
Müsste das nicht:

Code:
LinkedList<Object>[] = LinkedList<Typ>[]

heißen?

Denn Typ erbt doch von Object aber nicht umgekehrt.

Oder vertue ich mich da gerade?


& hättest du irgendeine weitere Erklärung oder besser noch gutes Tutorial für Whitecards?
Gehört habe ich das schon mal, aber sinnvoll benutzt noch nie (mir erschloss sich der Anwendungszweck noch nie, eventuell da mir das Prinzip noch nicht klar genug ist?!).
 
ascer schrieb:
Arrays deshalb, weil es mitunter viele Listen sind und ich eine relativ gute Hashfunktion dafür habe, man will ja nicht zu viel Performance verschenken ;)
[...]
Und ja, ich brauche eine zweidimensionale Datenstruktur und wollte diese als Array von LinkedLists anlegen, weil die Listen, die ich bekomme, eben schon fertig zum "Gebrauch" sind und das Array soll sie mir einfach nur alle halten. Warum ein Array? Wie gesagt, ich hab eine relativ vernünftige Hashfunktion, die mir für die Listen hashes errechnet, sodass ich sehr fix nachgucken kann, welche Liste wo im Array ist.
Dafür gibt es doch die HashMap?!
Code:
HashMap<LinkedList<SomeType>> hMap = new HashMap<LinkedList<SomeType>>();
hMap.put("Liste 1", new LinkedList<SomeType>());
LinkedList<SomeType> selectedList = hMap.get("Liste 1");


Oder hat deine Hash-Funktion irgendwelche besonderen Eigenschaften, die du benötigst?
 
Der Hash wird beim erstellen einer Liste berechnet anhand der Sachen, die reinkommen.

Oder anders gesagt: Die Funktion gab es schon und ich hab sie einfach kopiert ^^

Eventuell überarbeite ich die Datenstrukturen doch nochmal ;)
 
ascer schrieb:
Müsste das nicht:

Code:
LinkedList<Object>[] = LinkedList<Typ>[]

heißen?

Denn Typ erbt doch von Object aber nicht umgekehrt.

Oder vertue ich mich da gerade?

Nein, das ist schon richtig (so vom Gefühl her), allerdings funktioniert beides nicht, weil Generics und Arrays bei Java nicht wirklich zusammen gehen. Es gibt Möglichkeiten (Reflection), aber meist ist es besser auf Collections (etwa ArrayList) auszuweichen.

Ohne Näheres über das Programm zu wissen, würde ich auch denken, dass HashMap die geeignete Datenstruktur zum Halten der Listen wäre.
 
Was genau funktioniert nicht? Ich würde vorschlagen einfach mit debugger das ganze durchzugehen. Vielleicht liegt das Problem ganz wo anders.

Code:
LinkedList<Object>[] = LinkedList<Typ>[]
ich verstehe nicht wieso man OOP hier überhaupt einsetzt? Man muss doch verstehen was Typensicher heißt. Wenn man immer nur auf Object cast'et dann macht man sicher was falsches!
 
Ich sehe das Performance Problem auch nicht.

Im Gegenteil:
  • Sollte das Array der Listen sich jemals verändern, ist der Array-Ansatz hinfällig.
  • Bleibt sie konstant, sollte über das verwenden von ImmutableListen (siehe Guava Lib) nachgedacht werden. Diese sind zum einen type- und thread-safe und zum anderen Platzsparender (gemäß Doku).

Weiterhin will ich anmerken, dass Arrays von Listen bisher nie ein Zeichen von gutem, lesbaren und wartbaren Code waren. Ich würde daher um jeden Preis auf sowas verzichten...
 
Alles klar, vielen Dank für die Comments :)
 
Zurück
Oben