Java 在嵌套类中实现的比较器接口

Java 在嵌套类中实现的比较器接口,java,arrays,nested,comparator,ocpjp,Java,Arrays,Nested,Comparator,Ocpjp,我是stackoverflow.com的新手,但每当我遇到问题时,我经常使用它来搜索答案,但现在我找不到任何搜索问题的结果,所以我在这里问:) 我正在学习OCPJP SE 7认证,考试1Z0-804,我正在使用一本书(afaik只有一本,Ganesh\Sharma的一本) 在关于Comparator接口的集合一章中,本书提供了使用Comparator和Comparable接口对Student元素数组进行排序的示例,但问题是关于Comparator的: import java.util.*; c

我是stackoverflow.com的新手,但每当我遇到问题时,我经常使用它来搜索答案,但现在我找不到任何搜索问题的结果,所以我在这里问:) 我正在学习OCPJP SE 7认证,考试1Z0-804,我正在使用一本书(afaik只有一本,Ganesh\Sharma的一本) 在关于Comparator接口的集合一章中,本书提供了使用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));
    }
}

请帮助:D提前感谢。

没有真正的理由不实际实施可比
比较器

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

请参阅以获取进一步讨论。

如果您控制该类(如果它是一个类而不是一个接口),则可以将
比较器实现为被比较对象的静态嵌套类。但是,您希望根据目标类本机不支持的顺序(无论是通过
可比性
还是通过提供
比较器
类)来比较未控制的类的实例,这一点并不少见。在这种情况下,您必须创建自己的、单独的
比较器

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

即使您控制了所有内容,是否将
Comparator
s实现为顶级类也有一定的难度。我不知道你为什么叫它“不舒服”;就我自己而言,我通常会尽量避免嵌套类。还要注意的是,无论是否嵌套,
Comparator
实现类都将被编译到一个单独的类文件中。

每个编译单元有多个类实际上是Java不推荐使用的特性。您应该总是喜欢嵌套类。如果您使用单独的
比较器
,那么最好将其源代码放在单独的文件中。这并不是支持或反对嵌套
比较器
类的论据。很可能是原始源代码的来源书为了方便和清晰而将其呈现出来。@Serhiy-这与使用嵌套类实现
比较器的问题有什么关系?当然,但在某些情况下,您可能需要按学生的姓名排序,在其他情况下,您可能需要按学生的cgpa排序,当您需要比较方法的两个或多个不同实现时,您不能在需要比较的类中实现它,对吗?但是如果我需要两个不同的实现,我可以简单地创建两个嵌套类,比如Student.StudentCGPA和Student.StudentName
compareTo():为了给类的用户排序对象,这里是要使用“Student”类compare()的用户:如果开发人员没有提供compareTo())方法进行比较,或者用户希望更改逻辑以比较同一类的两个对象,而不更改类本身的代码(学生)。
@OldCurmudgeon可能我的问题与他的问题无关,但您的答案也与他的问题无关。。因为问题是:“为什么我不能使用嵌套类(在学生内部)?”。而不是“为什么我不应该实现
comprator
Comparable
?”。@Serhiy for compare您不必编写嵌套类,对吗?有时你只有.class文件,比如“Student”,你不能修改它的源代码,所以你不能编写嵌套类,但是是的,如果你有src代码,那么你可以这样做,但实际上,你在第一种情况下使用了campare()(即src不可用),这是我希望的完美答案!:D我没有考虑你解释的具体情况,如果我不能访问一个类,我就不能将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());
    }
}
    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);
        }
    });
}