There are two interface that can be used to sort objects in a list or array in java. They are java.lang.Comparable and java.util.Comparator. We all know java.util.Arrays
and java.util.Collections
has sort() method to sort an array or a list. But if you want to make the sorting success, you should let the object in the array or list implement java.lang.Comparable
first.
1. Sort String Array Example
We can use Arrays.sort()
method to do it.
public void sortStringArray() { // Create a String array. String codingLangArr[] = {"Java", "C++", "c", "Python", "Perl", "Php", "Visual Basic"}; Arrays.sort(codingLangArr); // Print out array item after ording. for(String codingLang : codingLangArr) { System.out.println(codingLang); } }
Output for above example code. Please note the uppercase character order first than lowercase character, because uppercase character’s ascii code is small than lowercase ascii code. Character C ‘s ascii code is 67 while c ‘s ascii code is 99.
2. Sort String List Example
Collections.sort()
method can be used to do it.
public void sortStringList() { // Create a String list. List<String> osList = new ArrayList<String>(); osList.add("Windows"); osList.add("Linux"); osList.add("MacOS"); osList.add("IOS"); osList.add("android"); osList.add("Unix"); Collections.sort(osList); // Print out list item after ordering. for(String os : osList) { System.out.println(os); } }
Output for above example code. You can see uppercase character order first than lowercase character.
3. Sort Date List Example
public void sortDateList() { try { // Create a SimpleDateFormat object for Date String converting. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // Create a Date list. List<Date> dateList = new ArrayList<Date>(); dateList.add(sdf.parse("2017-01-01")); dateList.add(sdf.parse("2016-01-01")); dateList.add(sdf.parse("2015-09-01")); dateList.add(sdf.parse("2057-02-01")); dateList.add(sdf.parse("2117-08-01")); dateList.add(sdf.parse("2117-01-02")); Collections.sort(dateList); // Print out each Date in the list after ordering. for(Date dateObj : dateList) { System.out.println(sdf.format(dateObj)); } }catch(ParseException ex) { ex.printStackTrace(); } }
Output for above code.
4. Sort Custom Java Object Example.
Above examples can run successfully because the String and Date class all implement java.lang.Comparable
interface.
So if you want to make your java object sortable, you should let it implement Comparable interface also. Otherwise you will meet errors.
When your java class implement Comparable interface, you should override it’s compareTo() method. Just like the java.util.Date’s compareTo() method, the method return an int value.
- Return 0 means compared object are equal.
- Return negative int means source object is less than the compared object.
- Return positive int means source object is greater than the compared object.
Below is the class which implement Comparable interface.
It will sort UserAccount object by it’s id field in descending order.
public class UserAccount implements java.lang.Comparable<UserAccount>{ private int id; private String userName; private String password; private Date registDate; private int salary ; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Date getRegistDate() { return registDate; } public void setRegistDate(Date registDate) { this.registDate = registDate; } public long getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } public UserAccount(int id, String userName, String password, Date registDate, int salary) { super(); this.id = id; this.userName = userName; this.password = password; this.registDate = registDate; this.salary = salary; } @Override public String toString() { StringBuffer retBuf = new StringBuffer(); retBuf.append("User id : "); retBuf.append(this.id); retBuf.append(" , name : "); retBuf.append(this.userName); retBuf.append(" , password : "); retBuf.append(this.password); retBuf.append(" , regist date : "); // Convert Date to String. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); retBuf.append(sdf.format(this.registDate)); retBuf.append(" , salary : "); retBuf.append(this.salary); return retBuf.toString(); } @Override public int compareTo(UserAccount target) { // Sort ascending //int ret = this.id- target.id; // Sort descending. int ret = target.id - this.id; return ret; } }
Run below code to see the result.
public void sortUserAccountList() { try { // Create a SimpleDateFormat object for Date String converting. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // Create a UserAccount list. List<UserAccount> uaList = new ArrayList<UserAccount>(); uaList.add(new UserAccount(1, "tom", "tom123", sdf.parse("2012-01-01"), 10000)); uaList.add(new UserAccount(3, "henry", "henry123", sdf.parse("2011-05-06"), 1000)); uaList.add(new UserAccount(6, "jack", "jack123", sdf.parse("2008-11-09"), 5000)); uaList.add(new UserAccount(4, "jackie", "jackie123", sdf.parse("2010-10-01"), 10200)); uaList.add(new UserAccount(5, "steven", "steven123", sdf.parse("2009-01-08"), 9000)); uaList.add(new UserAccount(2, "kate", "kate123", sdf.parse("2016-10-08"), 50000)); // Sort the list. Collections.sort(uaList); // Print out list item after sort. for(UserAccount ua : uaList) { System.out.println(ua.toString()); } }catch(Exception ex) { ex.printStackTrace(); } }
Output
But how about sort UserAccount object by it’s salary? Should we change the code? No, java.util.Comparator
can help you to sort UserAccount by multiple fileds.
5. Create Multiple Comparator To Sort UserAccount By Multiple Fields.
You can create multiple comparator class, each class implement java.util.Comparator interface to sort UserAccount list by multiple UserAccount filed.
The class should override Comparator’s compare(UserAccount o1, UserAccount o2) method. The method has two parameter. It return an int value.
- Return 0 means o1 equals to o2.
- Return negative int means o1 less than o2.
- Return positive int means o1 greater than o2.
We create two comparators for UserAccount class.
UserAccountSalaryComparator
Used to sort UserAccount list by salary.
public class UserAccountSalaryComparator implements Comparator<UserAccount> { @Override public int compare(UserAccount o1, UserAccount o2) { // Order ascending. //int ret = o1.getSalary() - o2.getSalary(); // Order descending. int ret = o2.getSalary() - o1.getSalary(); return ret; } }
UserAccountRegistDateComparator
Used to sort UserAccount list by register date.
public class UserAccountRegistDateComparator implements Comparator<UserAccount> { @Override public int compare(UserAccount o1, UserAccount o2) { // Order ascending. int ret = o1.getRegistDate().compareTo(o2.getRegistDate()); // Order descending. //int ret = o2.getRegistDate().compareTo(o1.getRegistDate()); return ret; } }
Sort UserAccount list use above comparators
public void sortUserAccountList() { try { // Create a SimpleDateFormat object for Date String converting. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // Create a UserAccount list. List<UserAccount> uaList = new ArrayList<UserAccount>(); uaList.add(new UserAccount(1, "tom", "tom123", sdf.parse("2012-01-01"), 10000)); uaList.add(new UserAccount(3, "henry", "henry123", sdf.parse("2011-05-06"), 1000)); uaList.add(new UserAccount(6, "jack", "jack123", sdf.parse("2008-11-09"), 5000)); uaList.add(new UserAccount(4, "jackie", "jackie123", sdf.parse("2010-10-01"), 10200)); uaList.add(new UserAccount(5, "steven", "steven123", sdf.parse("2009-01-08"), 9000)); uaList.add(new UserAccount(2, "kate", "kate123", sdf.parse("2016-10-08"), 50000)); System.out.println(""); // Order the list by salary. Collections.sort(uaList, new UserAccountSalaryComparator()); // Print out list item after ordering. for(UserAccount ua : uaList) { System.out.println(ua.toString()); } System.out.println(""); // Order the list by regist date. Collections.sort(uaList, new UserAccountRegistDateComparator()); // Print out list item after ordering. for(UserAccount ua : uaList) { System.out.println(ua.toString()); } }catch(Exception ex) { ex.printStackTrace(); } }
Output
6. Difference Between Comparable and Comparator
- If you crate a new java class which need to be sortable, it should implement
java.lang.Comparable
interface. - If you need to make an exist java class sortable, and the exist class dose not implement
java.lang.Comparable
interface. You can create multiple Comparator class for the exist class. The comparator class should implementjava.util.Comparator
interface. java.util.Comparator
can be used to create comparator for other class, despite whether the class implementjava.lang.Comparable
interface or not.
[download id=”2065″]