J'ai une classe générique avec deux variables de type, qui implémente Java.lang.Comparable.
La classe publique DoubleKey <K, J> implémente Comparable <DoubleKey <K, J >> { clé privée K; clé privée J2; public DoubleKey (clé K1, clé2) { this.key1 = clé1; this.key2 = clé2; } public K getFirstKey () { renvoie this.key1; } public J getSecondKey () { renvoie ceci .key2; } // besoin d'une interface comparable public int compareTo (DoubleKey <K, J> aThat) { .. . } }
Parce que je l'ai implémenté avec Comparable, je dois écrire la méthode compareTo (). Parce que K, J peut être deTOUT TYPE, je ne parviens pas à les comparer complètement. Y at-il un moyen de pouvoir attraper tous les types possibles (Primitive, Wrapper, Object) dans la comparaison? Merci pour l'aide!
pour résumer ce qui précède et le transformer en un code fonctionnel, il s’agit de:
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;
}
}
Souhaitez-vous introduire une exigence selon laquelle K
et J
ont un ordre naturel que vous pouvez utiliser? Dans ce cas, vous pouvez déclarer votre classe DoubleKey
comme ceci:
class DoubleKey<K extends Comparable<K>, J extends Comparable<J>>
Vous pouvez ensuite définir la variable compareTo
de votre DoubleKey à votre guise. Vous pouvez faire des choses comme:
getFirstKey().compareTo(aThat.getFirstKey())
Vous ne pouvez toutefois comparer aucune instance de K
à une instance de J
. Il n'y a pas d'ordre défini sur ces types.
Si ces types n'ont pas nécessairement un ordre naturel (beaucoup n'en ont pas), vous pouvez utiliser un Comparator<K>
et un Comparator<J>
en tant que paramètres du constructeur de votre DoubleKey
. Une classe qui fait déjà cela et que vous pouvez utiliser comme exemple est l'excellent Maps class de Google Guava (voir spécifiquement les méthodes newTreeMap
et les limites des types qu'elles acceptent).
public class DoubleKey < K implémente Comparable <K>, J implémente Comparable <J >> implémente Comparable <DoubleKey <K, J >> { public int compareTo (DoubleKey <K, J> que) { int cmp = this.key1.compareTo (that.key1); if (cmp = = 0) cmp = this.key2.compareTo (that.key2); Renvoie cmp; } }
Première façon: utilisez hashCodes, comme
public int compareTo(DoubleKey<K,J> aThat){
getFirstKey().hashCode() + getSecondKey().hashCode() - aThat.getFirstKey().hashCode() + aThat.getSecondKey().hashCode();
}
(vous devriez penser plus à la formule)
Deuxième manière: Ajouter un comparateur au constructeur
public DoubleKey(K key1, J key2, Comparator cmp){
Comme souvent, il existe une bibliothèque qui peut résoudre votre problème: Apache Commons lang3 . J'utilise souvent Paire <L, R> instances comme clés. Ils mettent en œuvre Comparable.
Vous devrez définir une règle quand un DoubleKey<K,J>
est plus petit, plus grand ou égal à celui-ci. C'est ce que fait la comparaison. Peut-être, c'est ce que je suppose, cela n'a pas beaucoup de sens de comparer aux instances de DoubleKey<K,J>
.
Si vous ne prenez pas réellement les soins comment ils sont commandés et que vous devez seulement mettre en œuvre any ordering, essayez ceci:
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());
}