Создайте сравнение с универсальным классом, который реализует сопоставимый - PullRequest
18 голосов
/ 16 февраля 2011

У меня есть универсальный класс с двумя переменными типа, который реализует 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){
        ...
    }

}

Поскольку я реализовал это с помощью Comparable, мне нужно написать метод compareTo (). Поскольку K, J может быть типа ANY , у меня возникают проблемы с тем, как их полностью сравнить. Есть ли способ уловить все возможные типы (Primitive, Wrapper, Object) в сравнении? Спасибо за помощь!

Ответы [ 6 ]

12 голосов
/ 04 июля 2013

Итак, чтобы подвести итог вышесказанному и объединить его в рабочий код, это:

    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;
    }
}
8 голосов
/ 16 февраля 2011

Хотели бы вы ввести требование, чтобы K и J имели естественный порядок, который вы можете использовать? В этом случае вы можете объявить свой класс DoubleKey следующим образом:

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

Затем вы можете определить compareTo вашего DoubleKey, как вам нравится. Вы можете делать такие вещи, как:

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

Вы не можете сравнить ни один экземпляр K с экземпляром J. Для этих типов порядок не определен.

Если эти типы не обязательно имеют естественное упорядочение (многие не имеют), вы можете взять Comparator<K> и Comparator<J> в качестве параметров для конструктора вашего DoubleKey. Класс, который уже делает это, и который вы можете использовать в качестве примера, это отличный класс Maps Google Guava (см. Конкретно методы newTreeMap и границы типов, которые они принимают).

4 голосов
/ 16 февраля 2011
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;
    }
}
0 голосов
/ 13 августа 2013

Как это часто бывает, существует библиотека, которая может решить вашу проблему: Apache Commons lang3 .Я часто использую Пара экземпляры в качестве ключей.Они реализуют Comparable.

0 голосов
/ 16 февраля 2011

Первый способ: используйте hashCodes, например

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

(вы должны больше думать о формуле)

Второй способ: добавить компаратор в конструктор

public DoubleKey(K key1, J key2, Comparator cmp){
0 голосов
/ 16 февраля 2011

Вам нужно будет определить правило , когда a DoubleKey<K,J> меньше, больше или равно этому. Это то, что делает сравнение. Может быть, это мое настоящее предположение, не имеет смысла сравнивать с экземплярами DoubleKey<K,J>.

Если вы на самом деле не заботитесь как они заказаны и им нужно только реализовать любой заказ, попробуйте это:

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());
}
...