2010-03-19 23 views
48

Tengo un Collection genérico y estoy tratando de averiguar cómo puedo ordenar los elementos que contiene. He intentado algunas cosas pero no puedo hacer que funcionen.Cómo ordenar una colección <T>?

Respuesta

65

Colecciones por sí mismas no tienen un orden predefinido, por lo tanto, debe convertirlos a un java.util.List. A continuación, puede utilizar una forma de java.util.Collections.sort

Collection<T> collection = ...; 

List<T> list = new ArrayList<T>(collection); 

Collections.sort(list); 
// or 
Collections.sort(list, new Comparator<T>(){...}); 

// list now is sorted 
+3

Aunque esto resuelve el problema, esto no será la forma más rápida de hacerlo, a menos que la colección en sí ya sea una Lista. – Fortega

+3

@Fortega: Entonces, ilumíname cuál es LA forma más rápida de ordenar una Colección general conservando todos sus elementos. Por cierto, este es exactamente el método utilizado por Google Collections 'Ordering.sortedCopy'. –

+0

Depende del tipo de la colección. Para las colecciones cuyo método toArray() (llamado en el constructor de ArrayList) necesita iteración sobre todos los elementos (por ejemplo: un conjunto), la ordenación puede necesitar un bucle adicional sobre todos los elementos. Puede usar google collections TreeMultiset, que permite duplicados. Aunque las diferencias probablemente no sean muy grandes y en el mismo orden de magnitud. – Fortega

1

Aquí hay un ejemplo. (Estoy usando CompareToBuilder clase de Apache por conveniencia, aunque esto se puede hacer sin usarlo.)

import java.util.ArrayList; 
import java.util.Calendar; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.Date; 
import java.util.HashMap; 
import java.util.List; 
import org.apache.commons.lang.builder.CompareToBuilder; 

public class Tester { 
    boolean ascending = true; 

    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.put("actionId", new Integer(1234)); 
     map.put("eventId", new Integer(21) ); 
     map.put("fromDate", getDate(1)  ); 
     map.put("toDate", getDate(7)  ); 
     list.add(map); 

     map = new HashMap<String, Object>(); 
     map.put("actionId", new Integer(456)); 
     map.put("eventId", new Integer(11) ); 
     map.put("fromDate", getDate(1)  ); 
     map.put("toDate", getDate(1)  ); 
     list.add(map); 

     map = new HashMap<String, Object>(); 
     map.put("actionId", new Integer(1234)); 
     map.put("eventId", new Integer(20) ); 
     map.put("fromDate", getDate(4)  ); 
     map.put("toDate", getDate(16)  ); 
     list.add(map); 

     map = new HashMap<String, Object>(); 
     map.put("actionId", new Integer(1234)); 
     map.put("eventId", new Integer(22) ); 
     map.put("fromDate", getDate(8)  ); 
     map.put("toDate", getDate(11)  ); 
     list.add(map); 


     map = new HashMap<String, Object>(); 
     map.put("actionId", new Integer(1234)); 
     map.put("eventId", new Integer(11) ); 
     map.put("fromDate", getDate(1)  ); 
     map.put("toDate", getDate(10)  ); 
     list.add(map); 

     map = new HashMap<String, Object>(); 
     map.put("actionId", new Integer(1234)); 
     map.put("eventId", new Integer(11) ); 
     map.put("fromDate", getDate(4)  ); 
     map.put("toDate", getDate(15)  ); 
     list.add(map); 

     map = new HashMap<String, Object>(); 
     map.put("actionId", new Integer(567)); 
     map.put("eventId", new Integer(12) ); 
     map.put("fromDate", getDate(-1)  ); 
     map.put("toDate", getDate(1)  ); 
     list.add(map); 

     System.out.println("\n Before Sorting \n "); 
     for(int j = 0; j < list.size(); j++) 
      System.out.println(list.get(j)); 

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

     System.out.println("\n After Sorting \n "); 
     for(int j = 0; j < list.size(); j++) 
      System.out.println(list.get(j)); 
    } 

    public static Date getDate(int days) { 
     Calendar cal = Calendar.getInstance(); 
     cal.setTime(new Date()); 
     cal.add(Calendar.DATE, days); 
     return cal.getTime(); 
    } 

    public class HashMapComparator2 implements Comparator { 
     public int compare(Object object1, Object object2) { 
      if(ascending) { 
       return new CompareToBuilder() 
        .append(
         ((HashMap)object1).get("actionId"), 
         ((HashMap)object2).get("actionId") 
        ) 
        .append(
         ((HashMap)object2).get("eventId"), 
         ((HashMap)object1).get("eventId") 
        ) 
       .toComparison(); 
      } else { 
       return new CompareToBuilder() 
        .append(
         ((HashMap)object2).get("actionId"), 
         ((HashMap)object1).get("actionId") 
        ) 
        .append(
         ((HashMap)object2).get("eventId"), 
         ((HashMap)object1).get("eventId") 
        ) 
       .toComparison(); 
      } 
     } 
    } 
} 

Si usted tiene un código específico que se está trabajando y está teniendo problemas, puede publicar su código seudo ¡y podemos intentar ayudarte!

+0

Thx por su respuesta, pero tengo una colección genérica este ejemplo no funciona para mí – Mercer

4

No puede si T es todo lo que obtiene. Tienes que tener el que se inyecta por el proveedor a través de:

Collection<T extends Comparable> 

o pasar en el comparador a través del método Collections.sort (...)

9

Un Collection no tiene un orden, por lo que quieren ordenarlo no tiene sentido. Puede ordenar List instancias y matrices y los métodos para hacerlo son Collections.sort() y Arrays.sort()

6

Si su objeto de colecciones es una lista, utilizaría el método de clasificación, tal como se propone en las otras respuestas.

Sin embargo, si no es una lista, y no les importa en qué tipo de objeto de colección se devuelve, creo que es más rápido para crear un TreeSet en lugar de una lista:

TreeSet sortedSet = new TreeSet(myComparator); 
sortedSet.addAll(myCollectionToBeSorted); 
+0

TreeSet requiere que se implemente Comparable, si desea que el conjunto esté ordenado. Esto es lo que suelo hacer cuando necesito una Colección ordenada. TreeSet también tirará duplicados. – David

+1

TreeSet no requiere que se implemente Comparable si usa un Comparador. Sin embargo, tienes razón sobre los duplicados. – Fortega

+0

OOPS- se perdió el comparador sentado allí. Siempre implemento Comparable, así que lo extrañé por completo. – David

1

suponiendo que haya una lista de objetos de tipo Person, utilizando la expresión Lambda, puede ordenar los apellidos de los usuarios, por ejemplo, de la siguiente manera:

import java.util.Arrays; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.List; 

class Person { 
     private String firstName; 
     private String lastName; 

     public Person(String firstName, String lastName){ 
      this.firstName = firstName; 
      this.lastName = lastName; 
     } 

     public String getLastName(){ 
      return this.lastName; 
     } 

     public String getFirstName(){ 
      return this.firstName; 
     } 

     @Override 
     public String toString(){ 
      return "Person: "+ this.getFirstName() + " " + this.getLastName(); 
     } 
    } 

    class TestSort { 
     public static void main(String[] args){ 
      List<Person> people = Arrays.asList(
            new Person("John", "Max"), 
            new Person("Coolio", "Doe"), 
            new Person("Judith", "Dan") 
      ); 

      //Making use of lambda expression to sort the collection 
      people.sort((p1, p2)->p1.getLastName().compareTo(p2.getLastName())); 

      //Print sorted 
      printPeople(people); 
     } 

     public static void printPeople(List<Person> people){ 
      for(Person p : people){ 
       System.out.println(p); 
      } 
     } 
    } 
Cuestiones relacionadas