简体   繁体   English

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

[英]Comparator Interface implemented in a nested class

I'm new on stackoverflow.com but I often used it to search for answers whenever I had a problem, but now I can't find any result searching for my problem so I'm asking here :) I'm studying for the OCPJP SE 7 certification, exam 1Z0-804, and I'm using a book (there is only one available afaik, Ganesh\\Sharma's one) In the collections chapter, about the Comparator interface, the book provide this example of using both the Comparator and the Comparable interface to sort an array of Student elements, but the question is about the Comparator: 我是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));
    }
}

So it creates a new class only for using the Comparator interface with two Student objects, but I think this is very uncomfortable so I wonder: why can't I use a nested class (within Student)? 所以它创建了一个新类,仅用于将Comparator接口与两个Student对象一起使用,但我认为这非常不舒服,所以我想知道:为什么我不能使用嵌套类(在Student中)? Like this: 像这样:

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

The book says nothing about using nested classes instead of normal ones, but I can't see why it should be bad to do like this... Is there any problem with my code (the 2nd one)? 这本书没有提到使用嵌套类而不是普通类,但是我不明白为什么这样做会不好...我的代码(第二个)有什么问题吗? Should I follow what the book says because my implementation of Comparator is wrong? 我是否应该遵循本书所说的内容,因为我对比较器的实现是错误的? (Note: the code compiles and runs without problem, with the expected output in both cases) (注意:代码编译并运行没有问题,在两种情况下都有预期的输出)

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

Please help :D Thanks in advance. 请帮忙:D先谢谢。

You can implement a Comparator as a static nested class of the one being compared, if you are in control of that class (and if it is a class rather than an interface). 如果您控制该类(并且它是一个类而不是一个接口),您可以将Comparator实现为被Comparator的静态嵌套类。 It is not at all uncommon, however, that you want to compare instances of a class that you do not control, according to an order that the target class does not support natively (whether by being Comparable or by providing a Comparator class). 但是,根据目标类本身不支持的顺序(无论是通过Comparable还是通过提供Comparator类),您想要比较您无法控制的类的实例并不罕见。 In that case you must create your own, separate Comparator . 在这种情况下,您必须创建自己的独立Comparator

Even when you control everything, it is somewhat a matter of taste whether to implement Comparator s as top-level classes. 即使您控制所有内容,是否将Comparator实现为顶级类也是一种品味问题。 I'm not sure why you call it "uncomfortable"; 我不确定你为什么称之为“不舒服”; myself, I usually prefer to avoid nested classes when I can. 我自己,我通常喜欢尽可能避免使用嵌套类。 Note, too, that whether you nest or not, the Comparator implementation class will be compiled to a separate class file. 另请注意,无论您是否嵌套, Comparator实现类都将编译为单独的类文件。

There's no real reason why you shouldn't actually implement both Comparable and 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());
    }
}

It is often more appropriate, however, to implement only Comparable and use other methods (such as inner classes or anonymous classes) to choose different orders. 但是,通常更适合仅实现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);
        }
    });
}

See here for further discussion. 请参阅此处以进一步讨论

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM