Создайте compareTo для универсального класса, который реализует Comparable

У меня есть общий класс с двумя переменными типа, который реализует 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 может иметь тип ЛЮБОЙ, у меня возникают проблемы с тем, как их полностью сравнивать. Есть ли способ уловить все возможные типы (примитив, обертка, объект) в сравнении? Спасибо за помощь!

Ответы

Ответ 1

чтобы суммировать сказанное выше и свести его вместе к рабочему коду:

    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;
    }
}

Ответ 2

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

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

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

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

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

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

Ответ 3

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;
    }
}

Ответ 4

Вам нужно определить правило, когда 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());
}

Ответ 5

Первый способ: используйте 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){

Ответ 6

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