Thursday, December 8, 2011

Java sorting function with Generics and Reflection

Fed up with writing sorting function every time??. This post will be a great relief for you.I am going to explain, How to write a java class which can be used to sort any type of java object collection in any field in any order. Thanks for introducing java 5 Generics and Reflection in Java.

/**
 * 
 */
package com.shims.support;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @author Semika Siriwardana
 *
 */
public class SHIMSSoringSupport<T> {

 private List<T> objectList;
 private String sortField = null;
 private String sortOrder = null;
 private static final String ASC = "asc";
 /**
  * @param 
  * 
  *   objectList 
  *    The list to be sorted
  * @param sortField
  *    The field name in which list to be sorted
  * 
  * @param sortOrder
  *    Sorting order.Either assending or decending. 
  */
 public SHIMSSoringSupport(List<T> objectList, String sortField,
   String sortOrder) {
   super();
   this.objectList = objectList;
   this.sortField = sortField;
   this.sortOrder = sortOrder;
 }
 
 /**
  * Perform soring
  * @param aClass
  * @throws Exception
  */
 public void sort(final Class aClass) throws Exception {
  
    final String _sortField = this.sortField;
    final String _sortOrder = this.sortOrder;
  
    Collections.sort(this.objectList, new Comparator<T>() {

    @Override
    public int compare(T o1, T o2) {
    
    try {
        Field sortField = aClass.getDeclaredField(_sortField);
        sortField.setAccessible(true);
     
        Object val1 = sortField.get(o1); 
        Object val2 = sortField.get(o2);
     
        if (val1 instanceof String && val2 instanceof String) {                                            
           if (ASC.equals(_sortOrder)){ //String field
               return ((String) val1).compareTo((String)val2);
           } else {
               return ((String) val2).compareTo((String)val1);
           }
        } else { //Numeric field  
           Number num1 = (Number)val1;
           Number num2 = (Number)val2;
      
           if (ASC.equals(_sortOrder)) {
               if (num1.floatValue() > num2.floatValue())  {
                  return 1;
               } else {
                  return -1;
               }
           } else {
                if (num2.floatValue() > num1.floatValue())  {
                    return 1;
                } else {
                    return -1;
                }
           }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } 
    return 0;
   }
  });
 }
}


Next, I will explain how to use above class to sort a list of objects. As You can see in the code, when instantiating class instance, You have to pass three constructor arguments into it.

objectList  - List of objects that are needed to get sorted.
sortField   - The field in which, You want to sort the collection.
sortOrder - The sorting order.This should be either 'asc' or 'desc'.

Following code shows, How to instantiate a class instance and invoke the sorting.

Think, You have a list of 'Employee' objects to sort.

List<Employee> empList = employeService.getAllEmployees(); 
   
SHIMSSoringSupport<Employee> soringSpt 
     = new SHIMSSoringSupport<Employee>(empList, "name", "asc");
soringSpt.sort(Employee.class);

The above code will sort the employee list by it's 'name' field in ascending order.

1 comments:

Share

Widgets