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 met
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 aClassCastException
for any elementse1
ande2
in the list).
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.
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());
}
...
}
}
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;
}
}
You can use sort
method in Collections
utility and your custom implementation of Comparator
interface.
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()
}
});