• 注册
  • 赞助本站

    • 微信
    • 支付宝
    • Q Q

    感谢一直支持本站的所有人!

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

      习题1.2.11

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

      要点分析

      1.  Date

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

      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
    • 585
    • 单栏布局 侧栏位置: