java - 使用具有多个比较器的比较器

标签 java arrays sorting compare comparator

我可以使用此代码中的所有简单比较器进行排序,但不能使用ComplexComparator。我不知道如何编码才能使其正常工作。任何建议/解释将不胜感激。

这是我的主程序:

package pkgTest;

import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        Student[] students = new Student[6];
        students[0] = new Student("Pete", 1989, 3.6);
        students[1] = new Student("Tomas", 1989, 3.9);
        students[2] = new Student("Helen", 1990, 3.6);
        students[3] = new Student("Steve", 1991, 3.7);
        students[4] = new Student("Natalie", 1993, 3.7);
        students[5] = new Student("John", 1992, 4.0);

        NameComparator byName
                = new NameComparator();
        BirthDateComparator byBirthDate
                = new BirthDateComparator();
        AverageComparator byAverage
                = new AverageComparator();

        ComplexComparator complexSorting
                = new ComplexComparator(byName,
                        byAverage);

        System.out.println("===============");
        System.out.println("Before sorting:");
        System.out.println("===============");
        for (Student student : students) {
            System.out.println(student.getName()
                    + " // " + student.getBirthDate()
                    + " // " + student.getAverage());
        }

        Arrays.sort(students, complexSorting);

        System.out.println("==============");
        System.out.println("After sorting:");
        System.out.println("==============");
        for (Student student : students) {
            System.out.println(student.getName()
                    + " // " + student.getBirthDate()
                    + " // " + student.getAverage());
        }
    }
}

以下是其余类(class):

package pkgTest;

public class Student {

    private String name;
    private int birthDate;
    private double average;

    public Student(String name, int birthDate,
            double average) {
        this.name = name;
        this.birthDate = birthDate;
        this.average = average;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getBirthDate() {
        return this.birthDate;
    }

    public void setBirthDate(int birthDate) {
        this.birthDate = birthDate;
    }

    public double getAverage() {
        return this.average;
    }

    public void setAverage(double average) {
        this.average = average;
    }
}


package pkgTest;

import java.util.Comparator;

public class ComplexComparator implements Comparator<Student> {

    public ComplexComparator(Comparator<Student> one,
            Comparator<Student> another) {
    }

    @Override
    public int compare(Student one, Student another) {
        /*This is the part that
        I just couldn't figure
        it out to get it work.

        It has to work no matter
        which 2 of the 3 comparators
        I use to set the input
        parameters of ComplexComparator.

        I have to make it work by
        modifying only this part of
        the code.*/
    }
}


package pkgTest;

import java.util.Comparator;

public class AverageComparator implements Comparator<Student> {

    @Override
    public int compare(Student one, Student another) {
        if (one.getAverage()
                < another.getAverage()) {
            return -1;
        } else if (one.getAverage()
                == another.getAverage()) {
            return 0;
        } else {
            return +1;
        }
    }
}

package pkgTest;

import java.util.Comparator;

public class BirthDateComparator implements Comparator<Student> {

    @Override
    public int compare(Student one, Student another) {
        if (one.getBirthDate()
                < another.getBirthDate()) {
            return -1;
        } else if (one.getBirthDate()
                == another.getBirthDate()) {
            return 0;
        } else {
            return +1;
        }
    }
}


package pkgTest;

import java.util.Comparator;

public class NameComparator implements Comparator<Student> {

    @Override
    public int compare(Student one, Student another) {
        return one.getName().
                compareToIgnoreCase(another.getName());
    }
}

最佳答案

您必须像下面这样修改类ComplexComparator,至少......

import java.util.Comparator;

public class ComplexComparator implements Comparator<Student> {

    private Comparator<Student> comparatorOne;
    private Comparator<Student> comparatorTwo;

    public ComplexComparator(Comparator<Student> one,
            Comparator<Student> another) {
        this.comparatorOne = one;
        this.comparatorTwo = another;
    }

    @Override
    public int compare(Student one, Student another) {
        // make a first comparison using comparator one
        int comparisonByOne = comparatorOne.compare(one, another);

        // check if it was 0 (items equal in that attribute)
        if (comparisonByOne == 0) {
            // if yes, return the result of the next comparison
            return comparatorTwo.compare(one, another);
        } else {
            // otherwise return the result of the first comparison
            return comparisonByOne;
        }
    }
}

对于两个以上的Comparator,您将需要它们的List(或另一个重载的构造函数)和一个保持特定比较顺序的循环。

编辑

对于您有关排序顺序的额外要求,这可能会有所帮助:

    public class ComplexComparator implements Comparator<Student> {

    private Comparator<Student> comparatorOne;
    private Comparator<Student> comparatorTwo;
    private boolean orderOneAscending = true;
    private boolean orderTwoAscending = true;

    /**
     * Constructor without any sort orders
     * @param one   a comparator
     * @param another   another comparator
     */
    public ComplexComparator(Comparator<Student> one, Comparator<Student> another) {
        this.comparatorOne = one;
        this.comparatorTwo = another;
    }

    /**
     * Constructor that provides the possibility of setting sort orders 
     * @param one   a comparator
     * @param orderOneAscending sort order for comparator one 
     *      (true = ascending, false = descending)
     * @param another   another comparator
     * @param orderTwoAscending sort order for comparator two
     *      (true = ascending, false = descending)
     */
    public ComplexComparator(Comparator<Student> one, boolean orderOneAscending,
            Comparator<Student> another, boolean orderTwoAscending) {
        this.comparatorOne = one;
        this.comparatorTwo = another;
        this.orderOneAscending = orderOneAscending;
        this.orderTwoAscending = orderTwoAscending;
    }

    @Override
    public int compare(Student one, Student another) {
        int comparisonByOne;
        int comparisonByAnother;

        if (orderOneAscending) {
            /*  note that your lexicographical comparison in NameComparator 
                returns a negative integer if the String is greater!
                If you take two numerical Comparators, the order will
                turn into the opposite direction! */
            comparisonByOne = comparatorOne.compare(another, one);
        } else {
            comparisonByOne = comparatorOne.compare(one, another);
        }

        if (orderTwoAscending) {
            comparisonByAnother = comparatorTwo.compare(one, another);
        } else {
            comparisonByAnother = comparatorTwo.compare(another, one);
        }

        if (comparisonByOne == 0) {
            return comparisonByAnother;
        } else {
            return comparisonByOne;
        }
    }
}

只需尝试一下这些值并尝试一些修改即可熟悉有关比较和排序的常见问题。 我希望这会有所帮助...

关于java - 使用具有多个比较器的比较器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51706742/

相关文章:

arrays - swift - 使用协议(protocol)转换 Array 与 ArraySlice

Python在格式化表达式中对字典进行排序

python - 将具有负数的列表排序为字符串会产生意外结果

java - 如何找到 Jersey 使用的反序列化器

java - 面板重绘后 mouseListener 丢失

c - 为什么在C中,读取文件时必须使用字符数组?

java - Primefaces:如何获取 Java 中的当前排序顺序?

java - 拥有一个全java程序或一个调用不同jar文件的perl文件会更快吗?

java - 如何使用 PowerMock 和 Mockito 对 Files.java 中的 newDirectoryStream 进行部分模拟?

javascript - 使用Array.filter后如何获取多个值?