tags:

views:

437

answers:

3

Here is what I have-

How I can include multiple keys and their values in comparison? Right now I am only using employeeId but I wanted to include departmentId and other in my comparison for sorting...

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

public class Tester {

    boolean flag = false ;


    public static void main(String args[]) {
        Tester tester = new Tester() ;
        tester.printValues() ;
    }

    public void printValues ()
    {

        List<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>() ;
        HashMap<String,Object> map = new HashMap<String,Object>();


        map = new HashMap<String,Object>();
        map.put("employeeId", new Integer(1234)) ;
        map.put("departmentId", new Integer(110)) ;
        map.put("someFlag", "B") ;
        map.put("eventTypeId", new Integer(11)) ;
        map.put("startDate", new Date() ) ;
        map.put("endDate", new Date() ) ;
        list.add(map);


        map = new HashMap<String,Object>();
        map.put("employeeId", new Integer(456)) ;
        map.put("departmentId", new Integer(100)) ;
        map.put("someFlag", "B") ;
        map.put("eventTypeId", new Integer(11)) ;
        map.put("startDate", new Date() ) ;
        map.put("endDate", new Date() ) ;
        list.add(map);


        map = new HashMap<String,Object>();
        map.put("employeeId", new Integer(1234)) ;
        map.put("departmentId", new Integer(10)) ;
        map.put("someFlag", "B") ;
        map.put("eventTypeId", new Integer(17)) ;
        map.put("startDate", new Date() ) ;
        map.put("endDate", new Date() ) ;
        list.add(map);

        map = new HashMap<String,Object>();
        map.put("employeeId", new Integer(1234)) ;
        map.put("departmentId", new Integer(99)) ;
        map.put("someFlag", "B") ;
        map.put("eventTypeId", new Integer(11)) ;
        map.put("startDate", new Date() ) ;
        map.put("endDate", new Date() ) ;
        list.add(map);

        map = new HashMap<String,Object>();
        map.put("employeeId", new Integer(1234)) ;
        map.put("departmentId", new Integer(100)) ;
        map.put("someFlag", "B") ;
        map.put("eventTypeId", new Integer(11)) ;
        map.put("startDate", new Date() ) ;
        map.put("endDate", new Date() ) ;
        list.add(map);



        map = new HashMap<String,Object>();
        map.put("employeeId", new Integer(567)) ;
        map.put("departmentId", new Integer(200)) ;
        map.put("someFlag", "P") ;
        map.put("eventTypeId", new Integer(12)) ;
        map.put("startDate", new Date()  ) ;
        map.put("endDate", new Date() ) ;
        list.add(map);

        Collections.sort ( list , new HashMapComparator2 () ) ;

        for( int i = 0 ; i < list.size() ; i ++ ) {
            System.out.println(list.get(i));    
        }

        System.out.println("======================================");    


        flag = true ; // desc
        Collections.sort ( list , new HashMapComparator2 () ) ;

        for( int i = 0 ; i < list.size() ; i ++ ) {
            System.out.println(list.get(i));    
        }

    }

    public class HashMapComparator2 implements Comparator
    {
        public int compare ( Object object1 , Object object2 )
        {
            if ( flag == false )
            {


                Integer obj1Value = ( Integer ) ( ( HashMap ) object1 ).get ( "employeeId" ) ;
                Integer obj2Value = ( Integer ) ( ( HashMap ) object2 ).get ( "employeeId" ) ;

                return obj1Value.compareTo ( obj2Value ) ;
            }
            else
            {
                Integer obj1Value = ( Integer ) ( ( HashMap ) object1 ).get ( "employeeId" ) ;
                Integer obj2Value = ( Integer ) ( ( HashMap ) object2 ).get ( "employeeId" ) ;

                return obj2Value.compareTo ( obj1Value ) ;
            }
        }
    }


}
+2  A: 

First I would create a Class to store the data instead using using a List of HashMaps. Then make that class implement the Comparable interface which allows you determine a finely-grained comparison algorithm.

If you absolutely need to use a HashMap then I would create a class that extends HashMap AND implements Comparable. But I don't recommend that approach.

public class Foo extends HashMap implements Comparable {
  private boolean ascending = true;

  public int compareTo(Object bar) {
    int result;
    if (bar == null || !(bar instanceof Foo)) {
      result = -1;
    }
    Foo _rhs = (Foo)bar;
    result = new CompareToBuilder().append(get("employeeId"),_rhs.get("employeeId"))
                 .append(get("departmentId"),_rhs.get("departmentId")).toComparison();

    return (ascending ? result : -result);
  }

  public void setAscending(boolean asc) {
    ascending = asc;
  }
}

No guarantees that this code will compile or return correct results. I really like the CompareToBuilder

martinatime
any code snippet snippet for second approach? I guess using List<HashMap> is inevitable in my case. Would be helpful if some one can update my above example.
HonorGod
I'm an old school Java developer with absolutely no experience in using Generics but I will put an example in my answer with non-Generic code and you can adapt it for your use.
martinatime
martinatime>> Have you had a chance to work on the example ?
HonorGod
oh..sorry I missed your comment earlier!Will try your approach!
HonorGod
A: 

martinatime's answer is correct. Create a class to store your data. Then you put it into map that supports key sorting, such as TreeMap:

new TreeMap<Integer, YouNewClass>(new Comparator<YourNewClass>() {

 public int compare(YourNewClass o1, YourNewClass o2) {
       implement the method here as per your logic.
 }

});

Enjoy: http://java.sun.com/j2se/1.4.2/docs/api/java/util/TreeMap.html

Daniil
Just note, not sure why people are obsessed with generics. It makes the code easy to read especially in this case. If there are no generics - then just do casting to achieve exactly the same. Let us know of your end solution. Cheers!
Daniil
+1  A: 

The easiest is using the CompareToBuilder from commons-lang. Your example would look like this:

Map<String, Object> map1 = (Map<String, Object>) object1;
Map<String, Object> map2 = (Map<String, Object>) object2;
if ( flag == false ) {
    return new CompareToBuilder()
        .append(map1.get("employeeId"), map2.get("employeeId"))
        .append(map1.get("departmentId"), map2.get("departmentId"))
        .toComparison();
}
else {
    return new CompareToBuilder()
        .append(map2.get("employeeId"), map1.get("employeeId"))
        .append(map2.get("departmentId"), map1.get("departmentId"))
        .toComparison();
}

Or something like that. Anyway, I would definitely recommend that you use Genrics in your comparators, as suggested by Daniil.

Andre Rodrigues
If my sorting conditions change, should I be defining new Comparator class every time ?
HonorGod