Objekt-Array mit generischen Datentypen erstellen

  • Hi,
    im Rahmen einer Aufgabe muss ich ein Objekt-Array erstellen mit der Zuweisung eines generischem Datentypen.


    Es existiert eine Klasse HashList, die Objekte im Array sind auch von diesem Typ:

    Code
    1. class HashList<T extends Comparable<T>>


    Ich erstelle das Array mit

    Code
    1. private HashList<T>[] hashTable;


    was auch noch klappt, aber spätestens im Konstuktor weiß ich nicht mehr weiter, wenn ich das Array mit Größe erstellen möchte:

    Code
    1. HashTable(int length) {
    2. hashTable = new HashList<T>[length];
    3. }


    wo eclipse meckert: cannot create a generic array of HashList<T>
    habe schon vieles ausprobiert aber nichts klappt...


    Hat jemand eine Idee oder sogar Lösung?

  • So wärs richtig.

    Java
    1. HashTable(int length) {
    2. hashTable = new HashList[length];
    3. }


    Kann sein, dass du dann eine Warnung bekommst, aber auf die musst du dann eben pfeifen.

    nein ist es nicht.
    wenn du das schreibst, benutzt du die nicht generische version von der HashList.. das ist an der aufgabe herumbearbeitet.


    btt:
    was ist genau deine aufgabe?
    schreib mal den ganzen code deiner Klasse, die du schreibst.



    sieht der code deiner klasse ca so aus:

    Java
    1. class HashTable{
    2. private HashList<T>[] hashTable;
    3. HashTable(int length) {
    4. hashTable = new HashList<T>[length];
    5. }
    6. }


    ?


    da hast du dein problem es müsste

    Java
    1. class HashTable<T extends Comparable<T>>{
    2. private HashList<T>[] hashTable;
    3. HashTable(int length) {
    4. hashTable = new HashList<T>[length];
    5. }
    6. }


    sein

  • Aufgabe ist es, eine Hashtabelle zu erstellen in der Objekte gesammelt werden sollen (HashTable). Falls zwei zu speichernde Objekte den gleichen Hashwert haben, also den gleichen Platz im Array belegen), sollen beide gespeichert werden, dafür die HashList, welche in Wirklichkeit eine doppelt verkettete Liste ist.
    Alles was man zur verketteten Liste ist, ist der Header der Klasse wie ich ihn oben gepostet habe.
    Die HashTabellenklasse sieht bisher so aus:


    Wo halt im Konstruktor oben erwähnter Fehler auftaucht.


    Akeshihiro : Wenn ich das weglasse gibt's ne Exception beim kopilieren, die ich zwar umgehen kann indem ich dem Compiler sage, dass das Objekt vom richtigen Typ ist, aber die Warnungen kriege ich nicht weg, und ich glaube nicht, dass das so gedacht war^^

  • Musst du umbedingt ein Array benutzen, oder kannst du das auch nochmal in ne Liste verpacken?
    Also so in etwa:

    Code
    1. List<HashList<T>> hashTable = new LinkedList<HashList<T>>();
  • tut mir leid, ich hab jetzt ein bisschen rumprobiert.. ohne sinnvollen ergebniss ..
    generics haben wir in der schule kaum gemacht, und da ich jetzt in der fh fast ausschließlich c++ mache hilft das auch nicht
    PS: Templates in c++ sind nicht halb so lustig wie generics.. die können nämlich nix ;)

  • Xaw.4
    Leider muss ich dir sagen, dass du unrecht hast.


    Ob es euch passt oder nicht, aber man kann bei Arrays keine generische Instanziierung vornehmen, lediglich eine Deklaration. Die Instanziierung des Arrays MUSS nicht-generisch sein. Da kommt auch kein Error oder sonst was, lediglich eine Warnung, weil es sich dann um einen "unchecked"-Fall handelt, da keine "feste" Typenbindung vorhanden ist. Diese Warnung kann man aber mit

    Java
    1. @SuppressWarnings("unchecked")

    abschalten, dann weist auch der Compiler nicht mehr drauf hin. Und genau da ist das Problem, denn das was Xaw.4 meinte, war das Problem mit "rawtype" und das ist im Normalfall auch richtig, bei Arrays aber nicht. Auch wenn ihr glaubt, dass das nicht richtig ist oder so nicht gedacht war, es ist richtig und ob es so gedacht war, weiß ich nicht, kann aber durchaus sein. Wenn ihr auch bei der Instanziierung einen festen generischen Typ haben wollt, dann müsst ihr eben auf Collections zurückgreifen, wie etwa eine Liste, und den Kontrollmechanismus bezüglich der maximalen Größe usw. eben selber drumrum bauen.


    Zum Schluss noch ein Beispiel:

  • Ok, dann muss ich das wohl so machen. Danke für die Hilfen und Informationen.



    Edit: In der nächsten Aufgabe muss die Hashtabelle keine Listen beinhalten sondern die Tabelle beinhaltet direkt die Hashelemente vom Datentyp T. Wie erzeuge ich jetzt am besten das Array? Habe bisher folgendes, was für mich am plausibelsten ist:

    Code
    1. T[] hashTable;
    2. @SuppressWarnings("unchecked")
    3. OpenHashTable(int length) {
    4. hashTable = ((T[]) new Object[length]);
    5. }
  • Wie gesagt, ein generisches Array deklarieren geht, aber eben nicht Instanziiren. Die Map-Implementierungen verwenden dafür Wrapper-Objekte und wenn ich ehrlich bin, mir fällt gerade auch nix anderes ein.


    Beispiel:


    Was ich aber die ganze Zeit nicht verstehe ist: Wenn ihr eine Hashtabelle implementieren sollt, wie soll das dann nur mit dem Wert funktionieren? Wenn der Hashwert on-the-fly beim Einfügen generiert wird, dann ist das für das Speichern ja noch ok, aber wie kommt man denn dann wieder an die entsprechenden Werte dran? Bei einer Tabelle muss deswegen normalerweise noch ein Referenzwert, der als Key dient, übergeben werden und das war bislang noch gar nicht vorzufinden.

  • Hi, ich bin es wieder. Komme mit meiner Gruppe wieder nicht so recht weiter.
    wir haben ein Array eines generischen Datentypen

    Code
    1. T hashTable;


    Einzutragende Inhalte werden mit der in Java mitgeführten Hashmethode gehasht und ingetragen, sofern der Index leer ist (der Hashcode bildet den Index). Im Falle, dass der Index nicht leer ist soll durch doppeltes Hashing ein neuer Platz ermittelt werden. Wir müssen also eine eigene Hashmethode schreiben. Das Problem ist, dass wir nicht wissen, wie man mit einem Element vom Typ T arbeitet, man weiß ja nicht, was dahinter steckt bzw. wie das aussieht, sprich, man kennt die Zeichenlänge nicht, den Datentypen und kann diese auch nicht umwandeln.


    Weiß jemand was?

  • Normal sollte jedes Objekt seinen eigenen Hashcode haben (so steht es zumindestens in der Dokumentation zur hashCode Methode). Dadurch dürfte dann ja kein Index 2 mal vorkommen, esseitdenn das Objekt ist dasselbe. Was bringt es dir denn auch wenn dein Objekt 2 Hashcodes hat? Dann weißt du ja trotzdem nicht wo es jetzt in der HashMap steht...

  • Wir erstellen das HashArray mit einer festen Größe und reduzieren alle Hashcodes, die gebildet werden, so dass sie in das Array passen. Hat das Array die Größe 10, wird der Hashcode mit dem Modulo durch 10 dividiert und der Rest bildet den Index, sprich:

    Code
    1. int index = hashCode & hashTable.length;


    Ist dieser Index jetzt belegt, soll durch eine zweite Hashmethode so lange ein neuer Index gesucht werden, bis ein freier Platz gefunden wurde. Wir haben die zweite Hashmethode jetzt so gemacht, dass der bisherige Hashwert mit Modulo 11 immer weiter verringert wird, falls er kleiner als 0 ist, wird er wieder auf die Größe des Arrays gesetzt. Damit hat sich mein Problem/Frage auch erledigt =)