我目前正在为银行数据库应用程序设计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));
}
答案 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 8
,Stream API
,New 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
个子句。