• 中文
    • English
  • 注册
  • 查看作者
  • 《算法第四版》课后练习题1.2.11答案

    习题1.2.11

    根据Date的API实现一个 SmartDate 类型,在日期非法时抛出一个异常。

    要点分析

    1.  Date

    Date类的API如下(课本第48页):

    《算法第四版》课后练习题1.2.11答案

    Date类的实现如下(课本第56页):

    public class Date {
        private final int month;
        private final int day;
        private final int year;
    
        public Date(int m, int d, int y) {
            month = m;
            day = d;
            year = y;
        }
    
        public int month() {
            return month;
        }
    
        public int day() {
            return day;
        }
    
        public int year() {
            return year;
        }
    
        public String toString() {
            return month() + "/" + day() + "/" + year();
        }
    
        public static void main(String[] args) {
            String s = new Date(3,19,1997).toString();
            System.out.println(s);
        }
    }
    
    
    输出:
    3/19/1997

    2.  异常

    关于Java异常相关的知识,课本上并没有详细解释,这里也不再赘述,详解可以查看Java异常处理,本题主要用到抛出异常这个知识点。

    那么本题中的"日期非法"有哪几种情况呢?

    2.1.  非数字

    比如我们输入的是三,十九,一九九七,但是该类异常需要在测试类中捕获,所以不在本题的范围内

    2.2.  平年闰年

    比如2018年2月29日是非法的,闰年2月有29天,平年2月只有28天

    2.3.  不存在的日期

    比如2018年13月33日是非法的

    关于日期主要存在以上几种异常,那么我们如何捕获这些异常呢?

    首先,我想到的便是创建一个单独的方法,将年月日挨个使用if else 判断,实现起来比较麻烦。其实我们可以将一个日期转换为字符串再转换成日期,然后采用SimpleDateFormat类的parse方法进行判断[1] ,如果转换不成功,就会出现异常。

    public static boolean isValidDate(String str) {
          boolean convertSuccess=true;
         // 指定日期格式为四位年/两位月份/两位日期,注意yyyy/MM/dd区分大小写;
           SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm");
           try {
         // 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01
              format.setLenient(false);
              format.parse(str);
           } catch (ParseException e) {
              // e.printStackTrace();
    // 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
               convertSuccess=false;
           } 
           return convertSuccess;
    }

    参考答案

    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    
    public class Date implements Comparable<Date> {
        private final int month;
        private final int day;
        private final int year;
    
    
        public boolean isValidDate(String str) {
            boolean convertSuccess = true;
            SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
            try {
                format.setLenient(false);
                format.parse(str);
            } catch (ParseException e) {
                convertSuccess = false;
            }
            return convertSuccess;
        }
    
         public Date(int month, int day, int year) {
            String str = year + "/" + month + "/" + day;
    
            if (!isValidDate(str)) {
                throw new IllegalArgumentException(month + "/" + day + "/" + year + "不合法");
            }
            this.month = month;
            this.day = day;
            this.year = year;
    
        }
        public Date(String date) {
            if (!isValidDate(date)) {
                throw new IllegalArgumentException(date + "不合法");
            }
    //如果final变量选择在构造函数中初始化,那么当类有多个构造函数时
    //需要在每个构造函数中都对这个final变量进行初始化
            String[] fields = date.split("/"); //正则表达式
            month = Integer.parseInt(fields[0]);
            day = Integer.parseInt(fields[1]);
            year = Integer.parseInt(fields[2]);
            
        }
    
    
    
    /*    public boolean leap_year(int m, int d, int y) {
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                return true;
            }
            return false;
        }*/
    
    
        public int month() {
            return month;
        }
    
        public int day() {
            return day;
        }
    
        public int year() {
            return year;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Date)) return false;
            Date date = (Date) o;
            return month == date.month &&
                    day == date.day &&
                    year == date.year;
        }
    
        @Override
        public int hashCode() {
            int hash = 17;
            hash = 31*hash + month;
            hash = 31*hash + day;
            hash = 31*hash + year;
            return hash;
        }
    
        @Override
        public String toString() {
            return month() + "/" + day() + "/" + year();
        }
    
        @Override
        public int compareTo(Date that) {
            if (this.year  < that.year)  return -1;
            if (this.year  > that.year)  return +1;
            if (this.month < that.month) return -1;
            if (this.month > that.month) return +1;
            if (this.day   < that.day)   return -1;
            if (this.day   > that.day)   return +1;
            return 0;
        }
        public static void main(String[] args) {
            System.out.println(new Date(2, 29, 2000).toString()); //合法
            System.out.println(new Date(2, 290, 2001).toString()); //不合法
            System.out.println(new Date(200, 29, 2001).toString());//不合法
        }
    
    }

    参考资料

    [1] 孤傲苍狼

  • 0
  • 0
  • 0
  • 2.8k
  • 请登录之后再进行评论

    登录
    单栏布局 侧栏位置: