2016-04-07 11 views
0

Ich bin eine einfache LinkedList-Klasse implementieren und ich möchte Generics verwenden. Die Klassendeklaration ist:Java Generic formale Parameter

Dies ist ein Lehrbeispiel, so dass die abstrakten Eltern und die Schnittstelle auch meine eigenen sind. Das Problem entsteht, als ich erkannte, dass ich eine Klasse (E), die ebenfalls vergleichbar ist, hinzufügen und pflegen muss. Ich dachte, ich könnte das auf die Methoden beschränken, wo es tatsächlich einen Unterschied macht. Aber basierend auf den folgenden Kommentaren mag das mein grundlegendes Missverständnis sein.

Hier ist der Code:

public void addSorted(<E extends Comparable<E>> value) { 
    if (front == null || value.compareTo(front.word) <= 0) { 
     // insert at front of list 
     front = new ListNode<E>(value, front); 
    } else { 
     // insert in middle of list 
     ListNode<E> current = front; 
     while (current.next != null && current.next.word.compareTo(value) < 0) { 
     current = current.next; 
     } 
     current.next = new ListNode<E>(value, current.next); 
    } 
    } 

Es schien mir, dass, wenn ich nie dann anrufen addSorted wollen, warum sollte die bestimmte Klasse E ist beschränkt sein, die vergleichbare implementieren? Oder gibt es eine völlig andere Art, es zu tun, mit einem generischen Analog zu Instanzen?

Danke!

+2

Das ist nicht das ist korrekte SyntaxEs sollte entweder 'public' sein, > void addSorted (E-Wert) 'oder einfach' public void addSorted (E-Wert) ', wenn' E' ein Typparameter der Klasse ist. Wir brauchen mehr Informationen. –

+1

Wir können auch nicht, wenn Sie das Problem nicht beschreiben. – Savior

+4

Sie sollten Ihre Frage verbessern. Gibt es einen Kompilierungsfehler? Gibt es welche, welche? Gibt es stattdessen einen Laufzeitfehler? – Baltasarq

Antwort

1

Überlegen Sie, was passiert, wenn Sie in der Lage sind, sowohl add und addSorted auf einem LinkedList Beispiel zu nennen:

LinkedList<String> list = new LinkedList<>(); 
list.add("c"); list.add("a"); 
list.addSorted("b"); 

In diesem Fall, wo Sie "b" erwar in eine Liste eingefügt werden ["c", "a"]:

  • Es ist lexikographisch vor "c", so dass es am Anfang eingefügt werden konnte, was ["b", "c", "a"] ergibt;
  • Es ist lexikographisch nach "a", so dass es am Ende eingefügt werden konnte, was ["c", "a", "b"] ergibt;

Aber keine Liste wird danach wirklich "sortiert".

Für mich ist der einzige offensichtliche Weg, um diese Mehrdeutigkeit zu lösen, zu erzwingen alle fügt, um in einer sortierten Weise getan werden. Dies bedeutet, dass Sie eine Unterklasse von LinkedList schaffen sollte, SortedLinkedList, die die LinkedList.add Methode überschreibt:

class SortedLinkedList<E extends Comparable<E>> extends LinkedList<E> { 
    void add(E element) { 
    // The implementation of addSorted. 
    } 
} 

Im Allgemeinen ist die Art, wie ich Methoden behandeln würde, der sollte nur für bestimmte generische Typen ist, es zu tun Verwenden einer Methode, die eine Instanz der Klasse als ersten Parameter akzeptiert, außerhalb der Definition der Klasse (oder innerhalb der Definition der Klasse, aber definiert als static). Dies bedeutet, dass es nicht Teil der Schnittstelle der Klasse ist, also nicht für Klassen mit inkompatiblen generischen Typen vorhanden ist.

Zum Beispiel, wenn Sie eine sort Methode zu sortieren LinkedList s hinzufügen wollen, ist dies natürlich nur sinnvoll für diejenigen mit Comparable Elementen:

static <E extends Comparable<E>> void sort(LinkedList<E> list) { 
    // ... 
} 

Zum Beispiel:

LinkedList<String> strList = new LinkedList<>(); 
// ... Add elements. 
sort(strList); // OK. 

LinkedList<Object> objList = new LinkedList<>(); 
// ... Add elements. 
sort(objList); // Compiler error - Object is not a valid bound. 
+0

Ausgezeichnete Antwort. Ein paar Folgen: Nehmen wir an, ich wollte alle Verwendungen von LinkedList <> erfordern eine Unterklasse von Comparable, würde die richtige Klassendeklaration sein: public class LinkedList > erweitert AbstractList implementiert Liste {? Das ist was ich habe und es kompiliert und es scheint richtig zu funktionieren. Obwohl die Liste Schnittstellen Comparable und so weiter nicht erwähnt. Zweitens, ich nehme an, man könnte (ich würde nicht) machen "addSorted" erkennen, dass die Liste nicht schon sortieren, und dann sortieren Sie es zuerst. Ein boolescher Wert könnte verfolgen, ob die Liste bereits sortiert wurde. – pitosalas

+0

1) Ja, das ist richtig. Das '>' deklariert die Typvariable mit ihren Constraints; der folgende '' verwendet es einfach (genau wie Sie brauchen nur 'String something' um es zu deklarieren, aber' something' um es zu benutzen). –

+0

2) Nun, ich nehme an, Sie könnten es, aber es würde ein bisschen unordentlich werden. –