2010-03-10 4 views
4

Voici ce que j'avoir-Liste de tri des HashMaps en fonction des valeurs hashmap [pas] touches

Comment puis-je inclure plusieurs clés et leurs valeurs par rapport? En ce moment, je ne sers employeeId mais je voulais inclure departmentId et d'autres dans ma comparaison pour le tri ...

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) ; 
      } 
     } 
    } 


} 

Répondre

1

Le simple est d'utiliser la CompareToBuilder de commons-lang. Votre exemple ressemblerait à ceci:

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(); 
} 

Ou quelque chose comme ça. Quoi qu'il en soit, je recommande fortement que vous utilisiez Genrics dans vos comparateurs, comme suggéré par Daniil.

+0

Si mes conditions de tri changent, devrais-je définir une nouvelle classe Comparator à chaque fois? – jagamot

3

D'abord, je voudrais créer un classe pour stocker les données au lieu d'utiliser une liste de HashMaps. Ensuite, faites en sorte que cette classe implémente l'interface Comparable qui vous permet de déterminer un algorithme de comparaison finement granulaire.

Si vous avez absolument besoin d'utiliser un HashMap alors je créerais une classe qui étend HashMap AND implémente Comparable. Mais je ne recommande pas cette approche.

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; 
    } 
} 

Aucune garantie que ce code compilera ou renverra des résultats corrects. J'aime vraiment le CompareToBuilder

+0

un extrait de code pour une seconde approche? Je suppose que l'utilisation de la liste est inévitable dans mon cas. Serait utile si quelqu'un peut mettre à jour mon exemple ci-dessus. – jagamot

+0

Je suis un développeur Java old school avec absolument aucune expérience dans l'utilisation de Generics mais je vais mettre un exemple dans ma réponse avec du code non-Generic et vous pouvez l'adapter pour votre usage. – martinatime

+0

martinatime >> Avez-vous eu l'occasion de travailler sur l'exemple? – jagamot

0

La réponse de martinatime est correcte. Créez une classe pour stocker vos données. Ensuite, vous mettez dans la carte qui prend en charge le tri clé, comme TreeMap:

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

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

}); 

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

+0

Juste noter, pas sûr pourquoi les gens sont obsédés par les génériques. Cela rend le code facile à lire, surtout dans ce cas. S'il n'y a pas de génériques - alors faites juste le casting pour obtenir exactement la même chose. Faites-nous savoir de votre solution finale. À votre santé! – Daniil

Questions connexes