java - hacer - Cree un compareTo a una clase genérica que implemente comparable
java create comparator (6)
Tengo una clase genérica con dos variables de tipo, que implementa java.lang.Comparable.
public class DoubleKey<K,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; } // need for Comparable interface public int compareTo(DoubleKey<K,J> aThat){ ... } }
Becuase lo implementé con Comparable, necesito escribir el método compareTo (). Debido a que K, J puede ser de CUALQUIER tipo, tengo problemas para compararlos por completo. ¿Hay alguna manera de poder capturar todos los tipos posibles (Primitivo, Envoltorio, Objeto) en la comparación? ¡Gracias por la ayuda!
¿Le gustaría presentar un requisito de que K
y J
tengan un orden natural que pueda usar? En este caso puedes declarar tu clase DoubleKey
así:
class DoubleKey<K extends Comparable<K>, J extends Comparable<J>>
A continuación, puede definir el compareTo
su DoubleKey como desee. Puedes hacer cosas como:
getFirstKey().compareTo(aThat.getFirstKey())
Sin embargo, no se puede comparar ninguna instancia de K
con una instancia de J
No hay ordenamiento definido sobre esos tipos.
Si estos tipos no tienen necesariamente un orden natural (muchos no), puede tomar un Comparator<K>
y un Comparator<J>
como parámetros al constructor de su DoubleKey
. Una clase que ya hace esto que puede usar como ejemplo es la excelente clase de Google Guava Maps (consulte específicamente los métodos newTreeMap
y los límites de los tipos que aceptan).
Como suele ser el caso, existe una biblioteca que puede resolver su problema: Apache Commons lang3 . A menudo utilizo las instancias de Pair<L,R> como teclas. Implementan Comparable.
Primera forma: usar códigos hash, como
public int compareTo(DoubleKey<K,J> aThat){
getFirstKey().hashCode() + getSecondKey().hashCode() - aThat.getFirstKey().hashCode() + aThat.getSecondKey().hashCode();
}
(deberías pensar más en la fórmula)
Segunda forma: agregar comparador al constructor
public DoubleKey(K key1, J key2, Comparator cmp){
Tendrá que definir una regla cuando una DoubleKey<K,J>
sea más pequeña, más grande o igual a esta. Eso es lo que hace la comparación. Tal vez, esa es mi suposición real, no tiene mucho sentido compararla con las instancias de DoubleKey<K,J>
.
Si no le importa cómo se ordenan y solo necesita implementar cualquier orden, intente esto:
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());
}
así que para resumir lo dicho anteriormente y para confundirlo en un código de trabajo, esto es:
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;
}
}
public class DoubleKey< K implements Comparable<K>, J implements Comparable<J>> implements 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; } }