Sort Java Objects Using Comparable And Comparator

There are two interfaces 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 successful, you should let the object in the array or list implement java.lang.Comparable first.

1. Sort String Array Example.

  1. 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);
    	}
    }
  2. Below is the output for the above example code. Please note the uppercase character order first than lowercase character, because the uppercase character’s ASCII code is small than the lowercase
    ASCII code. Character C ‘s ASCII code is 67 while c ‘s ASCII code is 99.

    C++
    Java
    Perl
    Php
    Python
    Visual Basic
    c

2. Sort String List Example.

  1. The 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);
    	}
    }
  2. Below is the output for the above example code. You can see uppercase character order first than lowercase character.
    IOS
    Linux
    MacOS
    Unix
    Windows
    android

3. Sort Date List Example.

  1. Below source code can sort a java Date list.
    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();
    	}
    }
  2. Below is the output for the above code.
    2015-09-01
    2016-01-01
    2017-01-01
    2057-02-01
    2117-01-02
    2117-08-01

4. Sort Custom Java Object Example.

  1. The above examples can run successfully because the String and Date class all implement java.lang.Comparable interface.
  2. So if you want to make your java object sortable, you should let it implement the java.lang.Comparable interface also. Otherwise, you will meet errors.
  3. When your java class implements java.lang.Comparable interface, you should override it’s compareTo() method. Just like the java.util.Date‘s compareTo() method, the method returns an int value.
  4. Return 0 means compared objects are equal.
  5. Return negative int value means the source object is less than the compared object.
  6. Return positive int value means the source object is greater than the compared object.
  7. Below is the class which implements java.lang.Comparable interface. It will sort the 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;
    	}
    }
  8. Run the 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();
    	}
    }
  9. Below is the above source code execution result output.
    User id : 6 , name : jack , password : jack123 , regist date : 2008-11-09 , salary : 5000
    User id : 5 , name : steven , password : steven123 , regist date : 2009-01-08 , salary : 9000
    User id : 4 , name : jackie , password : jackie123 , regist date : 2010-10-01 , salary : 10200
    User id : 3 , name : henry , password : henry123 , regist date : 2011-05-06 , salary : 1000
    User id : 2 , name : kate , password : kate123 , regist date : 2016-10-08 , salary : 50000
    User id : 1 , name : tom , password : tom123 , regist date : 2012-01-01 , salary : 10000
  10. But how about sorting the UserAccount object by the salary field? Should we change the code? No, java.util.Comparator can help you to sort UserAccount by multiple fields.

5. Create Multiple Comparator To Sort UserAccount By Multiple Fields.

  1. You can create multiple comparator classes, each class implements java.util.Comparator interface to sort UserAccount list by multiple UserAccount fields.
  2. The class should override Comparator’s compare(UserAccount o1, UserAccount o2) method. The method has two parameters, and it returns an int value.
  3. Return 0 means o1 equals o2.
  4. Return negative int value means o1 less than o2.
  5. Return positive int value means o1 greater than o2.
  6. Now we create the following two comparators for UserAccount class.
  7. UserAccountSalaryComparator is 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;
    	}
    
    	
    }
  8. UserAccountRegistDateComparator is 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;
    	}
    
    }
  9. Run the below java code to 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();
    	}
    }
  10. Below is the above source code execution output result.
    User id : 2 , name : kate , password : kate123 , regist date : 2016-10-08 , salary : 50000
    User id : 4 , name : jackie , password : jackie123 , regist date : 2010-10-01 , salary : 10200
    User id : 1 , name : tom , password : tom123 , regist date : 2012-01-01 , salary : 10000
    User id : 5 , name : steven , password : steven123 , regist date : 2009-01-08 , salary : 9000
    User id : 6 , name : jack , password : jack123 , regist date : 2008-11-09 , salary : 5000
    User id : 3 , name : henry , password : henry123 , regist date : 2011-05-06 , salary : 1000
    
    User id : 6 , name : jack , password : jack123 , regist date : 2008-11-09 , salary : 5000
    User id : 5 , name : steven , password : steven123 , regist date : 2009-01-08 , salary : 9000
    User id : 4 , name : jackie , password : jackie123 , regist date : 2010-10-01 , salary : 10200
    User id : 3 , name : henry , password : henry123 , regist date : 2011-05-06 , salary : 1000
    User id : 1 , name : tom , password : tom123 , regist date : 2012-01-01 , salary : 10000
    User id : 2 , name : kate , password : kate123 , regist date : 2016-10-08 , salary : 50000

6. Difference Between Comparable and Comparator.

  1. If you create a new java class that need to be sortable, it should implement java.lang.Comparable interface.
  2. If you need to make an existing java class sortable, and the existing class does not implement java.lang.Comparable interface. You can create multiple Comparator classes for the existing class. The comparator class should implement java.util.Comparator interface.
  3. java.util.Comparator can be used to create comparator for other class, despite whether the class implement java.lang.Comparable interface or not.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.