web-dev-qa-db-ja.com

comparableを実装するジェネリッククラスへのcompareToを作成する

Java.lang.Comparableを実装する2つの型変数を持つジェネリッククラスがあります。

パブリッククラスDoubleKey <K、J>は、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(){
これを返す.key2; 
} 
 
 //比較可能なインターフェースが必要
 public int compareTo(DoubleKey <K、J> aThat){
 .. 。
} 
 
} 

Comparableで実装したので、compareTo()メソッドを記述する必要があります。 K、Jは[〜#〜] any [〜#〜]タイプである可能性があるため、それらを完全に比較する方法に問題があります。比較ですべての可能なタイプ(プリミティブ、ラッパー、オブジェクト)をキャッチできる方法はありますか?助けてくれてありがとう!

20
Jairo

上記のことを要約し、それを一緒に作業コードにパズルするには、これは次のとおりです。

    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

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のコンストラクタへのパラメータとして。例として使用できる既にこれを行うクラスは、Google Guavaの優れた Maps クラスです(特に、newTreeMapメソッドと、それらが受け入れる型の境界を参照してください)。

8
sjr
 public class DoubleKey <
 KはComparable <K>を実装し、
 JはComparable <J >>を実装します
は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

最初の方法:次のようにハッシュコードを使用します

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

(あなたは式についてもっと考えるべきです)

2番目の方法:コンストラクターにコンパレーターを追加する

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

よくあることですが、問題を解決できるライブラリ Apache Commons lang が存在します。キーとして Pair <L、R> インスタンスをよく使用します。それらはComparableを実装します。

0
Michael Scheper

ルールを定義する必要がありますwhen a DoubleKey<K,J>はこれよりも小さい、大きい、または等しいです。それが比較が行うことです。多分、それは私の推測です、DoubleKey<K,J>のインスタンスと比較することはあまり意味がありません。

実際に気にしない場合howそれらは順序付けされており、実装する必要があるのはany順序付けだけである場合は、次のように試してください。

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