簡體   English   中英

比較器接口在嵌套類中實現

[英]Comparator Interface implemented in a nested class

我是stackoverflow.com上的新手,但每當我遇到問題時我經常用它來搜索答案,但現在我找不到任何搜索我的問題的結果所以我在這里問:)我正在為OCPJP SE 7認證,考試1Z0-804,我正在使用一本書(只有一本可用的afaik,Ganesh \\ Sharma的一本)在收藏章節,關於Comparator界面,本書提供了這個使用比較器的例子和Comparable接口對Student元素數組進行排序,但問題是關於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));
    }
}

所以它創建了一個新類,僅用於將Comparator接口與兩個Student對象一起使用,但我認為這非常不舒服,所以我想知道:為什么我不能使用嵌套類(在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));
    }
}

這本書沒有提到使用嵌套類而不是普通類,但是我不明白為什么這樣做會不好...我的代碼(第二個)有什么問題嗎? 我是否應該遵循本書所說的內容,因為我對比較器的實現是錯誤的? (注意:代碼編譯並運行沒有問題,在兩種情況下都有預期的輸出)

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

請幫忙:D先謝謝。

如果您控制該類(並且它是一個類而不是一個接口),您可以將Comparator實現為被Comparator的靜態嵌套類。 但是,根據目標類本身不支持的順序(無論是通過Comparable還是通過提供Comparator類),您想要比較您無法控制的類的實例並不罕見。 在這種情況下,您必須創建自己的獨立Comparator

即使您控制所有內容,是否將Comparator實現為頂級類也是一種品味問題。 我不確定你為什么稱之為“不舒服”; 我自己,我通常喜歡盡可能避免使用嵌套類。 另請注意,無論您是否嵌套, Comparator實現類都將編譯為單獨的類文件。

還有就是為什么你不能真正實現沒有真正的理由ComparableComparator

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

請參閱此處以進一步討論

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM