我试图用compareTo方法对数组列表进行排序

时间:2014-03-18 00:56:22

标签: java arraylist compareto

我正在尝试按照字母顺序按名称排序银行帐户,然后按帐户中的金额从最多到最少排序。不幸的是,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);
        }
    }
}

1 个答案:

答案 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),也就是说,它们并不总是返回-101

注意2:当您计划覆盖equals(Object)hashCode()方法时,请注意强烈建议,但不要严格 x.compareTo(y) == 0等于x.equals(y),请参阅Comparable<T>.compareTo(T object)