4

私はstackoverflow.comの初心者ですが、問題が発生したときはいつでも回答を検索するためによく使用していましたが、今は問題を検索する結果が見つからないため、ここで質問しています:) OCPJP SE 7 認定、試験 1Z0-804、および私は本を使用しています (入手可能な本は 1 つだけです。Ganesh\Sharma のものです) コレクションの章で、コンパレーター インターフェイスについて、本は両方のコンパレーターを使用するこの例を提供しますおよび Student 要素の配列をソートするための Comparable インターフェイスですが、問題は Comparator に関するものです。

import java.util.*;

class Student implements Comparable<Student> {
    private String id, name;
    private Double cgpa;
    public String getName() {
        return name;
    }
    public String getId() {
        return id;
    }
    public Double getCgpa() {
        return cgpa;
    }
    public Student(String studentId, String studentName, double studentCGPA) {
        id=studentId;
        name=studentName;
        cgpa=studentCGPA;
    }
    public String toString() {
        return id+" "+name+" "+cgpa;
    }
    public int compareTo(Student that) {
        return this.id.compareTo(that.id);
    }
}

class StudentCGPA implements Comparator<Student> {
    public int compare(Student s1, Student s2) {
        return s1.getCgpa().compareTo(s2.getCgpa());
    }
}

class MyMainClass {
    public static void main(String[] args) {
        Student[] students =    {   new Student("cs011", "Lennon", 3.1),
                                    new Student("cs021", "McCartney", 3.4),
                                    new Student("cs012", "Harrison", 2.7),
                                    new Student("cs022", "Starr", 3.7),
                                };
        Arrays.sort(students, new StudentCGPA());
        System.out.println(Arrays.toString(students));
    }
}

したがって、2 つの Student オブジェクトで Comparator インターフェイスを使用するためだけに新しいクラスを作成しますが、これは非常に不快だと思うので、(Student 内で) ネストされたクラスを使用できないのはなぜでしょうか? このような:

import java.util.*;

class Student implements Comparable<Student> {
    private String id, name;
    private Double cgpa;
    public String getName() {
        return name;
    }
    public String getId() {
        return id;
    }
    public Double getCgpa() {
        return cgpa;
    }
    public Student(String studentId, String studentName, double studentCGPA) {
        id=studentId;
        name=studentName;
        cgpa=studentCGPA;
    }
    public String toString() {
        return id+" "+name+" "+cgpa;
    }
    public int compareTo(Student that) {
        return this.id.compareTo(that.id);
    }
    static class StudentCGPA implements Comparator<Student> {
        public int compare(Student s1, Student s2) {
            return s1.getCgpa().compareTo(s2.getCgpa());
        }
    }
}

class MyMainClass {
    public static void main(String[] args) {
        Student[] students =    {   new Student("cs011", "Lennon", 3.1),
                                    new Student("cs021", "McCartney", 3.4),
                                    new Student("cs012", "Harrison", 2.7),
                                    new Student("cs022", "Starr", 3.7),
                                };
        Arrays.sort(students, new Student.StudentCGPA());
        System.out.println(Arrays.toString(students));
    }
}

この本は、通常のクラスの代わりにネストされたクラスを使用することについて何も述べていませんが、なぜこのようにするのが悪いのかわかりません...私のコード(2番目のもの)に問題はありますか? Comparator の実装が間違っているので、本に書かれていることに従うべきですか? (注: コードは問題なくコンパイルおよび実行され、どちらの場合も期待どおりの出力が得られます)

[cs012 Harrison 2.7, cs011 Lennon 3.1, cs021 McCartney 3.4, cs022 Starr 3.7]

助けてください:D よろしくお願いします。

4

2 に答える 2

6

そのクラスを制御している場合 (およびそれがインターフェイスではなくクラスである場合) は、比較Comparator対象のクラスの静的なネストされたクラスとして aを実装できます。ただし、制御していないクラスのインスタンスを、ターゲット クラスがネイティブにサポートしていない順序に従って比較したいということは、まったく珍しいことではありません (存在するか、クラスを提供するかによって)。その場合、独自の別個の を作成する必要があります。ComparableComparatorComparator

Comparatorすべてを制御する場合でも、 s をトップレベル クラスとして実装するかどうかは好みの問題です。なぜ「不快」と呼ぶのかわかりません。私自身、できる限りネストされたクラスを避けることを通常は好みます。また、ネストするかどうかに関係なく、Comparator実装クラスは別のクラス ファイルにコンパイルされることに注意してください。

于 2014-10-07T14:01:00.353 に答える
-2

と の両方 Comparableを実際に実装してはならない本当の理由はありませんComparator

class Student implements Comparable<Student>, Comparator<Student> {

    private final String id;
    private final String name;
    private final Double cgpa;

    public String getName() {
        return name;
    }

    public String getId() {
        return id;
    }

    public Double getCgpa() {
        return cgpa;
    }

    public Student(String studentId, String studentName, double studentCGPA) {
        id = studentId;
        name = studentName;
        cgpa = studentCGPA;
    }

    @Override
    public String toString() {
        return id + " " + name + " " + cgpa;
    }

    @Override
    public int compareTo(Student that) {
        return this.id.compareTo(that.id);
    }

    @Override
    public int compare(Student o1, Student o2) {
        return o1.getCgpa().compareTo(o2.getCgpa());
    }
}

Comparableただし、別の順序を選択するには、他のメソッド (内部クラスや匿名クラスなど)のみを実装して使用する方が適切な場合がよくあります。

    class ByCgpa implements Comparator<Student> {

        @Override
        public int compare(Student o1, Student o2) {
            return o1.getCgpa().compareTo(o2.getCgpa());
        }

    }

    Collections.sort(list, new ByCgpa());

static void sortByCgpaAndName(Collection<Student> students) {
    Collections.sort(students, new Comparator<Student> () {

        @Override
        public int compare(Student o1, Student o2) {
            int byCgpa = o1.getCgpa().compareTo(o2.getCgpa());
            return byCgpa != 0 ? byCgpa : o1.name.compareTo(o2.name);
        }
    });
}

詳細については、こちらを参照してください。

于 2014-10-07T13:36:44.587 に答える