2016-08-05 4 views
0

das folgende Beispiel gegeben ...Gibt es eine Möglichkeit, eine verschachtelte Generikum Angabe ohne einen Typ zweimal in Java Angabe 8+

S bezeichnet einen Startknoten von ConcreteType A

T bezeichnet einen Endknoten ConcreteType B

E bezeichnet eine Kante mit S als Startknoten und T als Endknotens

Flankensatz hat einen Satz von Kanten durch eine Schnittstellenmethoden zugegriffen

SomeObject o gibt eine EdgeSet-Schnittstelle über eine Methode zurück SomeObject.getEdges();

Eine Klassendefinition unter Verwendung generics wie folgt definiert ...

public class EdgeSet<S extends Node, T extends Node, E extends Edge<S, T>> { ... } 

    public class SomeObject { 

     protected EdgeSet<ConcreteNodeA, ConcreteNodeB, ConcreteEdge<ConcreteNodeA, ConcreteNodeB>> someEdgeSet; 

     ... 

     public EdgeSet<? extends ConcreteNodeA, ? extends ConcreteNodeB, ? extends ConcreteEdge<? extends ConcreteNodeA, ? extends ConcreteNodeB>> getEdges() { 
     //returns someEdgeSet... 
     } 
    } 

Verwendungsbeispiel ...

EdgeSet<? extends ConcreteNodeA, ? extends ConcreteNodeB, ? extends ConcreteEdge<? extends ConcreteNodeA, ? extends ConcreteNodeB>> exampleEdgeSet = o.getEdges(); 

Gibt es eine Möglichkeit, diesen Code zu definieren, und der Code, der das Mitglied nutzt Methode, ohne Dinge zweimal zu definieren?

Zum Beispiel:

public class EdgeSet<E extends Edge<S extends Node, T extends Node>> { ... }

EdgeSet<ConcreteEdge<? extends ConcreteNodeA, ? extends ConcreteNodeB>>

protected EdgeSet<ConcreteEdge<ConcreteNodeA, ConcreteNodeB>>

Wenn nicht, gibt es irgendwo, wo man durch einen RFC setzen können redundante Informationen zu reduzieren?

Antwort

1

Gibt es eine Möglichkeit, diesen Code zu definieren, und den Code, der die Methode member verwendet, ohne die Dinge zweimal zu definieren?

Angesichts Ihrer EdgeSet wie Sie gerade es definieren, ist die einzige Alternative, die ich sehe, ist eine Edge Implementierung zu verwenden, die nicht-generisch ist:

public class ConcreteEdgeAB extends Edge<ConcreteNodeA, ConcreteNodeB> { 
    // ... 
} 

Dann könnten Sie Erklärungen schreiben wie

protected EdgeSet<ConcreteNodeA, ConcreteNodeB, ConcreteEdgeAB> someEdgeSet; 

Das hat jedoch noch einige Redundanz, weil ConcreteNodeA und ConcreteNodeB die einzigen Typen sind, die Sie für S verwenden können und T, wenn Sie ConcreteEdgeAB als E verwenden. Außerdem ist es nicht so flexibel, wie Sie wahrscheinlich möchten.


Ich bin geneigt zu denken, dass das Hauptproblem ist, dass Sie über-parametrisiert haben.Wenn Ihr Typ Edge selbst durch die Knotentypen seiner Enden parametrisiert ist, ist es inhärent redundant, eine Menge von Kanten auch auf den Knotentypen zu parametrisieren - ein Rand Satz sollte nur für den Typ der Kanten parametrisiert werden müssen Es enthält:

+0

Hallo, das sieht ein großer Ausschnitt von Informationen mit Beispiel, das einzige mögliche Problem, das ich denken kann, ist, dass EdgeSet einen Verweis auf eine Instanz des ersten Knotens speichert. 'geschützt S parentNode;' (als ConcreteNodeA Instanz) 'protected Lieferant Lieferanten;' (als Methode-Referenz übergeben, um mit :: neu über Constructor) Would Java Lage sein, die Art von S und T schließen vom parametrierten Flankentyp? – Maiakaat

+0

Es klingt für mich, als ob du versuchst, dein EdgeSet zu viele Dinge machen zu lassen, aber ich denke, es muss einen Grund geben, warum du nicht nur eine der Standard-'Set'-Implementierungen verwendest. In jedem Fall, nein, wenn Sie möchten, dass 'EdgeSet' direkt auf die Typen der Knoten verweist, die Mitgliedskanten sind, dann müssen Sie es mit diesen Typen parametrisieren. Es ist mir nicht klar, ob Sie das wirklich tun, aber wenn ja, sollten Sie auch überlegen, ob es auch wichtig ist, es mit einem bestimmten 'Edge'-Typ zu parametrisieren. An dieser Stelle lehne ich ab, weiter auf Ihre spezifischen Bedürfnisse zu spekulieren. –

+0

Hallo, ja, es gibt Einschränkungen durch die Spring-Data-Implementierung von Neo4j (EdgeSet wird eigentlich von ConcurrentHashMap geerbt, da ich eine Long als Hash benötige, nicht die Objektidentität, wie HashSet implementiert ist). Es fügt einfach den parentNode hinzu (der benötigt wird, um die Konsistenz zu erhalten), er wird verwendet, um den ConcreteNodeA Parameter zu füllen, und einen Lieferanten (um neue Kanten über die Schnittstelle zu erzeugen), der nur ungefähr 8 Methoden hat. – Maiakaat