如何写一个比较器

时间:2015-04-01 11:00:13

标签: java comparator

public class Date {
    private int month; // must be 1-12
    private int day; // must be 1-31

    public int getMonth() {return month;}

    public int getDay() {return day;}

    public Date(int m, int d) {
        if (m >= 1 && m <= 12)
            month = m;
        else
            month = 1;

        if (d >= 1 && d <= 31)
            day = d;
        else
            day = 1;
    } // end constructor
} // end class Date

比较者类

import java.util.*;
public class DateComparator implements Comparator <Date>{
    public int compare(Date date1, Date date2){
            if (date1.getMonth() > date2.getMonth()){
                return 1;
            }
            else if(date1.getMonth() < date2.getMonth()){
                return -1;
            }
            else{ //if(date1.getMonth() == date2.getMonth()){
                if (date1.getDay() > date2.getDay()){
                    return 1;
                }
                if (date2.getDay() < date2.getDay()){
                    return -1;
                }
                else{// (date2.getDay() == date2.getMonth()){
                    return 0;
                }
            }
        }
    }

我试图为这个日期类写一个比较器,我想知道这是否是正确的方法。任何建议将不胜感激!

3 个答案:

答案 0 :(得分:5)

首先,这个问题似乎更适合Code Review。但是有一些概念需要解释,除了代码审查之外,所以我决定发表一个答案。

初稿

您的比较器可被视为初稿。它运行良好,并按指定比较两个Date个对象。做得好。

代码改进

许多if-else语句使得比较器有些笨拙且难以理解。请记住,compare方法不一定要返回-1,0或1.如果第一个参数小于第二个参数,它可以返回任何负数,如果第一个参数大于第二个参数,则返回任何正数一。只有0返回才是相等的。

由于月和日都表示为整数,因此您可以在一个小算术中使用它们。月份差异更重要 - 它更重 - 因此它必须更重

public int compare(Date date1, Date date2) {
    int monthDiff = date1.getMonth() - date2.getMonth();
    int dayDiff = date1.getDay() - date2.getDay();
    return monthDiff * 100 + dayDiff;
}

减法已产生负数,零或正数。所以使用它们。因子100使月差异比白天差异更重要。

如果月份差异不为0,则添加日差不会产生任何影响(因为因子为100)。只有月差为0时,日差才重要。

代码结构

以这种方式比较两个日期看起来非常自然。实际上,这是日期上的自然排序。如果类型具有这种自然顺序,您应该(必须)让它实现Comparable

public class Date implements Comparable<Date> {
    ...
    @Override
    public int compareTo(Date other) {
        int monthDiff = this.getMonth() - other.getMonth();
        int dayDiff = this.getDay() - other.getDay();
        return monthDiff * 100 + dayDiff;
    }
}

其他比较器

如果您觉得必须有其他比较器,可以随时添加它们。一个好的地方是Date类中的嵌套静态类(因为它们只属于它)。

让我们制作一个只考虑月份的比较器:

public class Date implements Comparable<Date> {
    ...
    public static final class MonthComparator implements Comparator<Date> {
        @Override
        public int compare(Date date1, Date date2) {
            return date1.getMonth() - date2.getMonth();
        }
    }
}

答案 1 :(得分:0)

他是一种(几乎)正确的方法。我写的几乎是因为这两个日期中的任何一个都可能是null,你应该检查一下。

除此之外,它看起来还不错。

答案 2 :(得分:0)

看起来没问题。在编写比较器时,你唯一需要记住的就是正确实现compare()方法并按照你的逻辑返回{1,-1,0}。