使用 Comparable 接口比较两个日期

Comparing two dates using Comparable interface

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

"Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 在 BankDatabase.showBefore(BankDatabase.java:234) 在 TransactionManager.showAllAccountsActionPerformed(TransactionManager.java:474) 在 TransactionManager.access1200 美元(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));
   }   
  if(d.month > month)
     return -1;
  if(d.month > month)
     return 1;

您在 equals 方法中有等效的 if 子句。

关于你的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 8 功能的更多信息,例如 Stream APINew Date/Time APIlambda

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