it-swarm.com.de

Erstellen Sie eine compareTo zu einer generischen Klasse, die Comparable implementiert

Ich habe eine generische Klasse mit zwei Typvariablen, die Java.lang.Comparable implementiert.

 public class DoubleKey <K, J> implementiert Comparable <DoubleKey <K, J >> {
 
 privater K-Schlüssel1; 
 privater J-Schlüssel2; [.____. .] 
 public DoubleKey (K-Taste1, J-Taste2) {
 this.key1 = key1; 
 this.key2 = key2; 
} 
 
 public K getFirstKey () {
 return this.key1; 
} 
 
 public J getSecondKey () {
 zurückgeben .key2; 
} 
 
 // Bedarf an der Comparable-Schnittstelle 
 public int compareTo (DoubleKey <K, J> aThat) {
 .. . 
} 
 
} 

Weil ich es mit Comparable implementiert habe, muss ich die compareTo () -Methode schreiben. Da K, J vonJEDEMTyp sein kann, habe ich Probleme, sie vollständig zu vergleichen. Gibt es eine Möglichkeit, alle möglichen Typen (Primitive, Wrapper, Object) im Vergleich abfangen zu können? Danke für die Hilfe!

18
Jairo

um das Gesagte zusammenzufassen und es zu einem Code zusammenzufügen, heißt das: 

    public class DoubleKey<K extends Comparable<K>, J extends Comparable<J>>
        implements Comparable<DoubleKey<K, J>> {

    private K key1;
    private J key2;

    public DoubleKey(K key1, J key2) {
        this.key1 = key1;
        this.key2 = key2;
    }

    public K getFirstKey() {
        return this.key1;
    }

    public J getSecondKey() {
        return this.key2;
    }

    public int compareTo(DoubleKey<K, J> that) {

        int cmp = this.getFirstKey().compareTo(that.getFirstKey());
        if (cmp == 0)
            cmp = this.getSecondKey().compareTo(that.getSecondKey());
        return cmp;
    }
}
12
olippuner

Möchten Sie eine Anforderung einführen, dass K und J eine natürliche Reihenfolge haben, die Sie verwenden können? In diesem Fall können Sie Ihre Klasse DoubleKey folgendermaßen deklarieren:

class DoubleKey<K extends Comparable<K>, J extends Comparable<J>>

Sie können dann die compareTo Ihres DoubleKey nach Belieben definieren. Sie können Dinge tun wie:

getFirstKey().compareTo(aThat.getFirstKey())

Sie können jedoch keine Instanz von K mit einer Instanz von J vergleichen. Für diese Typen ist keine Reihenfolge definiert.

Wenn diese Typen nicht notwendigerweise eine natürliche Reihenfolge haben (viele nicht), können Sie dem Konstruktor Ihrer DoubleKey einen Comparator<K> und einen Comparator<J> als Parameter übergeben. Eine Klasse, die dies bereits als Beispiel macht, ist die exzellente Maps class von Google Guava (siehe insbesondere die newTreeMap-Methoden und die Grenzen der akzeptierten Typen).

8
sjr
 öffentliche Klasse DoubleKey <
 K implementiert Comparable <K>, 
 J implementiert Comparable <J >> 
 implementiert Comparable <DoubleKey <K, J >> {
 
 public int compareTo (DoubleKey <K, J> that) {
 int cmp = this.key1.compareTo (that.key1); 
 if (cmp = = 0) cmp = this.key2.compareTo (that.key2); 
 Return cmp; 
} 
} 
4
paulmurray

Erster Weg: Verwenden Sie Hash-Codes, wie

 public int compareTo(DoubleKey<K,J> aThat){
     getFirstKey().hashCode() + getSecondKey().hashCode() - aThat.getFirstKey().hashCode() +   aThat.getSecondKey().hashCode();
 }

(Sie sollten mehr über die Formel nachdenken)

Zweiter Weg: Komparator zum Konstruktor hinzufügen

public DoubleKey(K key1, J key2, Comparator cmp){
0
Stan Kurilin

Wie häufig gibt es eine Bibliothek, die Ihr Problem lösen kann: Apache Commons lang3 . Ich benutze oft Pair <L, R> Instanzen als Schlüssel. Sie implementieren Comparable.

0
Michael Scheper

Sie müssen eine Regel definieren wenn a DoubleKey<K,J> kleiner, größer oder gleich dieser ist. Das ist, was Vergleich macht. Vielleicht ist das meine tatsächliche Vermutung, es macht keinen Sinn, mit Instanzen von DoubleKey<K,J> zu vergleichen.

Wenn Sie nicht wirklich wie bestellt sind und nur any bestellen müssen, versuchen Sie Folgendes:

public int compareTo(DoubleKey<K,J> that){
    // real codes needs checks for null values!
    return (this.key1.toString() + this.key2.toString()).compareTo(that.key1.toString() + that.key2.toString());
}
0
Andreas_D