我正在尝试按照字母顺序按名称排序银行帐户,然后按帐户中的金额从最多到最少排序。不幸的是,CompareTo方法似乎没有正常工作,唯一有效的部分是第二部分,它按数量进行排序。
BankAccount类
/**
* A bank account has a balance, the name of the account holder,
* and an account number. The balance can be changed by deposits
* and withdrawals.
*/
public class BankAccount implements Comparable<BankAccount> {
/**
* Constructs a bank account with a zero balance.
* @param name the name of the account holder
*/
public BankAccount(String name) {
this.name = name;
balance = 0;
accountNo = ++lastAccountNo;
}
/**
* Constructs a bank account with a given balance.
* @param initialBalance the initial balance
* @param name the name of the account holder
*/
public BankAccount(String name, double initialBalance) {
this.name = name;
balance = initialBalance;
accountNo = ++lastAccountNo;
}
/**
* Deposits money into the bank account.
* @param amount the amount to deposit
*/
public void deposit(double amount) {
double newBalance = balance + amount;
balance = newBalance;
}
/**
* Withdraws money from the bank account.
* @param amount the amount to withdraw
*/
public void withdraw(double amount) {
double newBalance = balance - amount;
balance = newBalance;
}
/**
* Gets the current balance of the bank account.
* @return the current balance
*/
public double getBalance() {
return balance;
}
/**
* Gets the name of the account holder.
* @returns the name of the account holder
*/
public String getName() {
return name;
}
/**
* Gets the account number of the account.
* @returns the account number of the account
*/
public int getAccountNo() {
return accountNo;
}
/**
* Returns a String representation of the BankAccount. The format
* is "name: accountNo balance"
* @returns a String representation of the BankAccount.
*/
public String toString() {
return name + ": AccountNo:" + accountNo + " balance:" + balance;
}
private double balance;
private String name;
private int accountNo;
private static int lastAccountNo=0;
public int compareTo(BankAccount b) {
if(this.name.compareTo(b.name) == 0 && this.balance > b.balance) return 0;
else if(this.name.compareTo(b.name) < 0 && this.balance < b.balance) return 1;
else if(this.name.compareTo(b.name) > 0 && this.balance == b.balance) return -1;
//else if(this.name.compareTo(b.name) == 0) return 0;
//else if(this.name.compareTo(b.name) < 0) return 1;
//else if(this.name.compareTo(b.name) > 0) return -1;
else if(this.balance == b.balance) return 0;
else if(this.balance < b.balance) return 1;
else if(this.balance > b.balance) return -1;
else return 0;
}
}
BankAccountTester
import java.util.ArrayList;
import java.util.Collections;
class BankAccountTester {
public static void main(String args[]) {
ArrayList<BankAccount> accounts = new ArrayList<BankAccount>();
accounts.add(new BankAccount("Louis Oliphant", 100.0));
accounts.add(new BankAccount("Louis Oliphant", 100.10));
accounts.add(new BankAccount("Louis Oliphant", 100.0));
accounts.add(new BankAccount("Jane Doe", 100.0));
accounts.add(new BankAccount("Jane Doe", 99.0));
accounts.add(new BankAccount("Jane Doe", 100.0));
System.out.println("*****Unsorted******");
for (BankAccount b : accounts) {
System.out.println(b);
}
System.out.println();
Collections.sort(accounts);
System.out.println("******Sorted******");
for (BankAccount b : accounts) {
System.out.println(b);
}
}
}
答案 0 :(得分:1)
你应该重新考虑你的逻辑。如果两个银行账户的名称不相等,那么金额的比较是不必要的,不是吗?
public int compare(BankAccount o1, BankAccount o2) {
int compareName = o1.getName().compareTo(o2.getName());
if (compareName == 0) {
// When the balance of the current amount is greater than the
// balance of the compared account, then the current accounts
// "precedes" the compared account, and thus -1 is returned.
// If the balance is less, than this account "follows" the
// compared account, and 1 is preceded.
// Otherwise, 0 is returned.
return (0 - Double.compare(o1.getBalance(), o2.getBalance()));
}
else {
return compareName;
}
}
或更短:
public int compare(BankAccount o1, BankAccount o2) {
if (o1.getName().compareTo(o2.getName()) < 0) { return -1; }
else if (o1.getName().compareTo(o2.getName()) > 0) { return 1; }
return (0 - Double.compare(o1.getBalance(), o2.getBalance()));
}
正如其他人提到的,我建议使用Comparator<T>
分隔sort()
作为compareTo()
方法的参数,而不是实现接口Comparable
的{{1}}方法。实现compareTo()
定义了对象的“自然”排序。您的订购看起来像特定于该情况的订单,而不是自然排序。请参阅Java : Comparable vs Comparator。
顺便说一句,在使用货币值时,您应该使用BigDecimal
而不是double
s。请参阅Double vs. BigDecimal?。
注1:当代码名称相等时,上面的代码块会返回字典差异,请参阅String.compareTo(String)
,也就是说,它们并不总是返回-1
,0
或1
。
注意2:当您计划覆盖equals(Object)
和hashCode()
方法时,请注意强烈建议,但不要严格 x.compareTo(y) == 0
等于x.equals(y)
,请参阅Comparable<T>.compareTo(T object)
。