Sort an ArrayList of objects?

2020-05-09 14:44发布

I need some help how to sort an ArrayList of objects. I have the superclass Account and two subclasses SavingsAccount and CreditAccount. Inside the Account class I have this method to call when I want to know the account number:

// Get account number
public String getAccountNumber() {
    return accountNumber;
}

I need to sort the account numbers to get the highest number of all accounts in the objects?

The ArrayList is like this:

ArrayList<Account> accountList = new ArrayList<Account>();

Could this be done in a simple and not to comlicated way? Thanks!

标签: java
7条回答
干净又极端
2楼-- · 2020-05-09 15:12

You can implement Comparable interface in your Account class. And then use java.util.Collections.sort(list) method.

class Account implements Comparable<Account >{
....

@Override
    public int compareTo(Account o) {

        return this.getAccountNumber().compareTo(o.getAccountNumber());
    }

...
}

}

查看更多
Anthone
3楼-- · 2020-05-09 15:14

For a start, why is an account number being represented as a string? Is it a number, or is it text? Anyway, it's absolutely possible to sort your list using Collections.sort:

Collections.sort(list, new Comparator<Account>() {
    @Override public int compare(Account x, Account y) {
        return x.getAccountNumber().compareTo(y.getAccountNumber();
    }
});

If that sorts them in the wrong sense for you (ascending instead of descending), reverse the comparison:

Collections.sort(list, new Comparator<Account>() {
    @Override public int compare(Account x, Account y) {
        return y.getAccountNumber().compareTo(x.getAccountNumber();
    }
});

Note that as these are strings, it will sort them in lexicographic order. If you were using numbers instead, that wouldn't be a problem.

An alternative which I wouldn't recommend in this case is to make Account implement Comparable<Account>. That's suitable when there's a single "natural" way of comparing two accounts - but I can see that you might want to sometimes sort by number, sometimes by the name of the account holder, sometimes by the funds within the account, sometimes by the date the account was created etc.

As an aside, it's not clear that you really need to sort this at all - if you just need to find the largest account number, you don't need to sort it, you just need to iterate and remember the account with the largest number as you go:

Account maxAccount = null;
for (Account account : accounts) {
    if (maxAccount == null || 
        account.getAccountNumber().compareTo(maxAccount.getAccountNumber()) > 0) {
        maxAccount = account;
    }
}
查看更多
叛逆
4楼-- · 2020-05-09 15:21
Collections.sort(accountList)

will work if Account implements Comparable<Account>. If not, you need to pass in a comparator

Collections.sort(accountList, new Comparator<Account>() {
  public int compare(Account a, Account b) {
    // Assumes account numbers are not null.
    return a.getAccountNumber().compareTo(b.getAccountNumber());
  }
});

From the javadoc:

public static <T extends Comparable<? super T>> void sort(List<T> list)

Sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list must implement the Comparable interface. Furthermore, all elements in the list must be mutually comparable (that is, e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the list).

查看更多
Melony?
5楼-- · 2020-05-09 15:28

I'm sorry to say your question is not very clear. What you mean by "I need to sort the account numbers to get the highest number of all accounts in the objects?" I guess you need to sort your ArrayList on the basis of accountNumber which is a String!!

To sort any objects in Java, they should implement the simple interface Comparable. Most of the Java built-in classes like String,Date etc already implement Comparable, and thats why we are able to sort them. For OUR classes WE should take the pain to tell the JVM on what basis it should sort OUR objects. You can tell this for Account class as shown below

public class Account implements Comparable<Account>{

private String accountNumber;

public int compareTo(Account anotherAcct) {
    // Do null Check for anotherAcct
    return this.getAccountNumber().compareTo(anotherAcct.getAccountNumber());
}

public String getAccountNumber() {
    return accountNumber;
}
}

Now simply call Collections.sort(accountList).

Below is the sample test code and result

            Account acct1 = new Account("AA1");
    Account acct2 = new Account("BB1");
    Account acct3 = new Account("AA2");
    Account acct4 = new Account("1FF");

    List<Account> accountList = new ArrayList<Account>();
    accountList.add(acct1);
    accountList.add(acct2);
    accountList.add(acct3);
    accountList.add(acct4);

    Collections.sort(accountList);
    System.out.println(accountList);

This printed

[Account [accountNumber=1FF], Account [accountNumber=AA1], Account [accountNumber=AA2], Account [accountNumber=BB1]]

ie in the decreasing alphabetical order. If you want the other way around (increasing order of alphabets) you can either call Collections.reverse(accountList) or go and change the compareTo() implementation as below.

    public int compareTo(Account anotherAcct) {
    // Do null Check for anotherAcct
    //return this.getAccountNumber().compareTo(anotherAcct.getAccountNumber());
    return anotherAcct.getAccountNumber().compareTo(this.getAccountNumber());
}

Sometimes you may be in a position where you cannot accomplish this using Comparable interface (may be because you don't have the source for that class or it is already implementing Comparable interface to sort on the basis of another attribute, say bank balance!). In this case you need to create a Comparator as below.

public class AccountNumberComparator implements Comparator<Account>{

@Override
public int compare(Account account1, Account account2) {
    // do null checks for both account1 and account2
    return account1.getAccountNumber().compareTo(account2.getAccountNumber());
}
}

Now simply call

Collections.sort(accountList,new AccountNumberComparator());

Advantage of this approach is you can create as many comparators you want like AccountBalanceComparator,AccountNameComparator etc on basis of different attributes, which can then be used to sort your list in different ways as you wish.

查看更多
6楼-- · 2020-05-09 15:32

Use Collections.sort(accountList ); to sort the ArrayList

查看更多
太酷不给撩
7楼-- · 2020-05-09 15:36

java.util.Collections.sort(list) - use it when Account implements Comparable.

java.util.Collections.sort(list, new Comparator<Account>(){
     public int compare(Account a,  Account b){
          return a.getAccountNumber().compareTo(b.getAccountNumber()
     }
});
查看更多
登录 后发表回答