将比较器与多个比较器一起使用

2022-08-22 00:00:00 arrays sorting compare java 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());
        }
    }
}

以下是其余类:

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,您将需要ListList(或另一个重载的构造函数)和一个保持特定比较顺序的循环。

编辑

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

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

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

相关文章