web-dev-qa-db-ja.com

カスタムcompareToの実装

@Override
public int compareTo(Object t) 
{
    if(t instanceof Student)
    {
        Student s = (Student)t;
        return (this.name.compareTo(s.name));
    }
    else
        return -1;
}

これは、名前に基づいて2つのcompareToオブジェクトを比較するための私のStudentメソッドの実装です。複数のフィールド、つまり名前と年齢の両方に基づいて、そのような2つのオブジェクトを比較することは可能ですか?

6
Anjan Baradwaj

はい、Comparator interface compareメソッドを使用して、異なるソートシーケンスに基づいて2つのオブジェクトを比較することができます。

ソートシーケンスクラスを作成する必要があります。 コンパレータを使用したユーザー定義オブジェクトの並べ替え

3
Prasad Kharkar

はい。ただし、最初に、実装しているComparableインターフェースを入力する必要があります。これがどのように見えるべきかです:

public class Student implements Comparable<Student> {
    private int age;
    private String name;
    @Override
    public int compareTo(Student s) {
        if (name.equals(s.name))
            return age - s.age;
        return name.compareTo(s.name));
    }
}

型付きインターフェースでどのようにComparable<Student>、生の型Comparableの代わりに、キャストする必要はありません。

15
Bohemian

Apache CompareToBuilder クラスは言及する価値があります。

リフレクションの有無にかかわらず実装できます

public int compareTo(Object o) {
    return CompareToBuilder.reflectionCompare(this, o);
}
1
kervin

上記のコードのcompareToメソッドは、オーバーライドではなく、 オーバーロード であることに注意してください。

実装しているinterface

public interface Comparable<T> {
    public int compareTo(T o);
}

あなたの実装:

@Override
public int compareTo(Object t) {
    //...
}

このインターフェースの元の作者であるJoshBlochは、彼の著書で Effective Java この理由だけで@Overrideアノテーションを使用するようにアドバイスしました。過負荷によって引き起こされたバグは、見つけるのがかなり難しい場合があります。

これらのオブジェクトを「複数のフィールドに基づいて」比較したいとおっしゃっています。これが「2つのフィールドに基づいて1つの方法で並べ替える」のか、「それぞれが1つのフィールドに基づいて複数の方法で並べ替える」のかはわかりません。ここの他の回答に示されているように、どちらも可能です。

ただし、これが最終的な収益です。

自分でクラスを作成しているように見え、このクラスの「自然順序付け」を定義したい場合は、Comparable<T>を実装する必要があります。複数の順序を定義する場合、または問題のクラスを制御しない場合は、Comparator<T>を実装するクラスで独自の順序を定義します( ここ を参照)。

0
varzeak