使用Comparable接口比较两个日期

时间:2016-05-05 06:58:54

标签: java compareto

我目前正在为银行数据库应用程序设计GUI。在我的GUI中,我有一个"列表帐户在"之前打开我试图编码的按钮,列出数据库中文本区域中的所有帐户,这些帐户的日期在用户输入文本字段的日期之前。我对Comparable接口背后的实现以及如何正确比较对象数组中的两个日期感到非常困惑。在我看来,我的ShowBefore方法逻辑是正确的,但我认为情况并非如此,我不知道为什么。我的问题在于BankDatabase的showBefore()方法,Date {s} compareTo()方法和GUI的ShowAllActions按钮。任何帮助将不胜感激。我收到了

"线程中的异常" AWT-EventQueue-0"显示java.lang.NullPointerException     在BankDatabase.showBefore(BankDatabase.java:234)     在TransactionManager.showAllAccountsActionPerformed(TransactionManager.java:474)     在TransactionManager.access $ 1200(TransactionManager.java:17)     在TransactionManager $ 13.actionPerformed(TransactionManager.java:202)     "

当我向gui输入任何日期时。

*我只发布了所需的最低限度方法

public class BankDatabase
{
private static final int GROW_SIZE = 2;
private static final int NOT_FOUND = -1;
private static final int ARRAY_SIZE = 100; //i added this
private Account[] bank;
private int num;

/**
default constructor
*/
public BankDatabase()
{
  num = 0;
  bank = new Account[ARRAY_SIZE];
}

public String showBefore( Date prevDate) 
{
  String temp = new String();
  for ( int i = 0; i < size(); i++)
  {
     if ( bank[i].getDate().compareTo(prevDate) == -1 )
     {
        temp += bank[i].toString(); // 
        temp += "\n";
     }
  }
  return temp;
}
import java.util.Calendar;
import java.util.StringTokenizer;

public class Date implements Comparable {
   private int invalidCheck = 0;
   private int day;
   private int month;
   private int year;

   /**
   Parameterized Constructor.
   @param d date
   */
   public Date(String d)
   {
      StringTokenizer st = new StringTokenizer(d, "/");
      month = Integer.parseInt(st.nextToken());
      day = Integer.parseInt(st.nextToken());
      year = Integer.parseInt(st.nextToken());
   }

   /**
   Copy Constructor.
   @param d date
   */
   public Date(Date d)
   {
      month = d.month;
      day = d.day;
      year = d.year;
   }

   /**
   Creates an instance with todays date
   */
   public Date()
   {
      Calendar c = Calendar.getInstance();
      this.day = c.get(Calendar.DAY_OF_MONTH);
      this.month = c.get(Calendar.MONTH) + 1;
      this.year = c.get(Calendar.YEAR);
   }

   /**
   Compare “this” with (Date) o; if “this” is before o, return -1; if “this” is equal
   to o return 0; if “this” is after o, return 1.
   @param o
   @return the value of the date
   */
   public int compareTo(Object o)
   {
      Date d = new Date((Date) o);

      if(d.year > year)
         return -1;
      if(d.year < year)
         return 1;
      if(d.month > month)
         return -1;
      if(d.month < month)
         return 1;
      if(d.day > day)
         return -1;
      if(d.day < day)
         return 1;
      return 0;
   }

   /**
   checks to see if certain dates are valid. Also checks 
   if it is a leap year to verify the correct amount of days 
   in February.
   @return true if the date is valid, false otherwise
   */
   public boolean isValid()
   {
      if (( month == Month.JAN || month == Month.MAR
            || month == Month.MAY || month == Month.JUL
            || month == Month.OCT || month == Month.OCT
            || month == Month.DEC )
            && ( day <= Month.DAYS_ODD && day > invalidCheck ) )
         return true;
      if (( month == Month.APR || month == Month.JUN
            || month == Month.SEP
            || month == Month.NOV )
            && ( day <= Month.DAYS_EVEN && day > invalidCheck ) )
         return true;

      boolean leapYear = false;
      if ( year % Month.QUADRENNIAL == invalidCheck 
            || year % Month.CENTENNIAL == invalidCheck
            || year % Month.QUATERCENTENNIAL == invalidCheck )
      {
         leapYear = true;
      }
      if (leapYear)
      {
         if (month == Month.FEB && day <= Month.DAYS_FEB + 1)
            return true;
      }
      if (month == Month.FEB && day <= Month.DAYS_FEB)
         return true;
      return false;
   }

   /**
   Return the name and date of the TeamMember as a String.
   @return name::price as a string.
    */
   public String toString()
   {
      return month + "/" + day + "/" + year;
   }

   /**
   day,month, and year are equal if they have the 
   same day, month, and year
   @param obj
   @return true if they are equal, false otherwise.
   */
   public boolean equals(Object obj)
   {
      if (obj instanceof Date)
      {
         Date d = (Date) obj;
         return d.day == day && d.month == month && d.year == year;
      }
      return false;
   }
}
public abstract class Account
{
   private static int numAccount = 1000; //incremented by 1 for each acc op.
   protected final int PERCENTAGE = 100;
   protected final int MONTH_PER_YEAR = 12;
   protected Profile holder; //account holder's profile
   protected int accNumber; //a sequence number from numAccount
   protected double balance;
   protected Date openOn; //the date the account is opened on

   /**
    parameterized constructor
    @param name String that will be the name
    @param phone String that will be the phone associated with the account
    */
   public Account(String name, String phone)
   {
      holder = new Profile(name, phone);
      accNumber = numAccount++;
      balance = 0;// 0 if deposit has to happen after
      openOn = new Date();
   }

   public Date getDate()
   {
      return openOn;
   }

public abstract String toString(); //subclass must implement this method
public class TransactionManager extends javax.swing.JFrame
{
   BankDatabase database = new BankDatabase();
   TransactionSimulator sim = new TransactionSimulator();
   ButtonGroup accType = new ButtonGroup();
   private Vector client;

   /**
    Creates new form TransactionManager
    */
   public TransactionManager()
   {
      initComponents();
      database = new BankDatabase();
      accType.add(checking);
      accType.add(savings);
      accType.add(moneyMarket);
      cbSpecialSavings.setEnabled(false);
      client = new Vector<String>();
   }
   private void showAllAccountsActionPerformed(java.awt.event.ActionEvent evt)                                                
   {                                                    
      Date openOn = new Date(dateBefore.getText());
      outputArea.append(database.showBefore(openOn));
   }   

2 个答案:

答案 0 :(得分:2)

关于showBefore()至少进行一些额外的检查

public String showBefore( Date prevDate)
{
    StringBuilder builder = new StringBuilder("");
    for ( int i = 0; i < size(); i++)
    {
        Account account = bank[i];
        if (account != null) {
            Date date = account.getDate();
            if (date != null && date.compareTo(prevDate) == -1 ) {
                builder.append(account.toString() + "\n")
            }
        }
    }
    return builder.toString();
}

并记住StringBuilder未同步的内容

在其他情况下,请详细了解Java 8Stream APINew Date/Time API

lambda功能
public String showBefore(LocalDate prevDate)
{
    StringBuilder builder = new StringBuilder("");
    Arrays.asList(bank).parallelStream().forEach(account -> {
        if (account != null) {
            LocalDate date = account.getDate();
            if (date != null && date.compareTo(prevDate) == -1 ) {
                builder.append(account.toString()).append("\n");
            }
        }
    });
    return builder.toString();
}

答案 1 :(得分:0)

  if(d.month > month)
     return -1;
  if(d.month > month)
     return 1;

if方法中有相应的equals个子句。