2010-11-10 23 views
5

Tengo HashMap<Object, Student> donde el Objeto es el ID del Estudiante y el Alumno es un objeto del Alumno.Ordene HashMap alfabéticamente por valor

¿Cómo puedo utilizar el HashMap por el nombre de los estudiantes, student->getName()?

+0

depende de lo que la tarea " quiere "que hagas" Como no hay "recurso", tal vez quiera que muestre/exporte a los estudiantes (en HashMap) en un orden particular ...de todos modos, la tarea es voluble de esa manera. –

+1

Dupe of http://stackoverflow.com/questions/1894081/what-is-the-easiest-way-to-sort-maps-according-to-values-in-java, http://stackoverflow.com/questions/2839003/sorting-in-hash-maps-in-java y probablemente muchos más. – BalusC

+2

Esta tiene que ser una de las 10 mejores preguntas de Java. –

Respuesta

13

Los HashMaps están intrínsecamente desordenados y no se pueden ordenar.

En su lugar, puede utilizar una implementación SortedMap, como TreeMap.
Sin embargo, incluso un mapa ordenado solo puede ordenar por sus claves.

Si desea ordenar por los valores, deberá copiarlos en una lista ordenada.

0

Los HashMaps no se pueden ordenar por sus valores. Un mapa está diseñado para búsquedas de tiempo constante basadas en la clave, por lo que ordenar por valores no debería ser necesario. Si necesita ordenar por nombre, sugiero usar un SortedSet y crear un comparador que ordena por los nombres.

class StudentComparator implements Comparator<Student> { 
    int compare(Student s1, Student s2) { 
     return s1.getName().compareTo(s2.getName()); 
    } 
} 

Si necesita tanto una búsqueda constante de tiempo y un conjunto ordenado por valor, entonces puede que tenga que mantener un mapa y un conjunto.

+0

a menos que sean 'nulos'. – SLaks

+0

sí, suponía que un estudiante siempre tendrá un nombre –

+1

Y que los estudiantes no son nulos. – SLaks

1

Los mapas no se pueden ordenar por valores. Sin embargo, puede hacer esto:

Collection<Student> students = map.values(); 

Collection.sort(new ArrayList<Student>(students)), new Comparator<Student>() { 
    public int compare(Student s1, Student s2) { 
     return s1.getName().compareTo(s2.getName()); 
    } 
}); 

Suponiendo, por supuesto, que necesita repetir los valores. (¿Por qué otra cosa podría querer ordenado así?)

Buena suerte.

+0

TreeMaps están ordenados. Decir que Maps en general no puede ser no es completamente exacto. Sí, sé que OP dijo usar un HashMap, pero dijiste Map, no HashMap. –

+1

Pedido por llaves. Dije ordenado por valores, no por llaves. – Todd

0

Definitivamente usaría una Nueva Clase que almacenará la llave y el Objeto.

Luego puede poner cada elemento del Mapa en una ArrayList en la forma de esta clase, y finalmente usar un comparador para ordenar el ArrayList, luego simplemente construye un nuevo Mapa. Código será algo como esto:

Map<Object, Student> valueMap = new LinkedHashMap<String, String>(); 
List<Student> pairValueList = new ArrayList<PairValue>(); 

PairValue p; 
for (Map.Entry<Object, Student> entry : map.entrySet()) { 
    Object key = entry.getKey(); 
    Student value = entry.getValue();   
    p = new PairValue(key, value); 
    pairValueList.add(p); 
} 

Collections.sort(pairValueList, new Comparator<PairValue>() { 
    @Override 
    public int compare(PairValue c1, PairValue c2) { 
    return c1.getLabel().compareTo(c2.getLabel()); 
    } 
}); 

for (PairValue pv : pairValueList) { 
    valueMap.put(pv.getValue(), pv.getStudent()); 
} 

El PairValue clase

class PairValue {  

    private Object value;  
    private Student student; 

    public PairValue(Object value, String student) { 
    this.value = value; 
    this.student= student; 
    } 

    public String getValue() { 
    return value; 
    } 

    public String getStudent() { 
    return student; 
    }  
} 

Esa es la forma en que se resolverán algunos problema similar que tenía en el pasado. Tenga en cuenta que la implementación del mapa devuelto debe ser un LinkedHashMap.

4

Es posible que no pueda ordenar un HashMap, pero ciertamente puede hacer algo que proporcione el mismo efecto. Pude ordenar mi HashMap < String, Entero > por el valor descendente del entero utilizando el excelente código publicado en el blog Javarevisited. El mismo principio se aplicaría a una cadena HashMap <, Cadena > objeto:

/* 
* Java method to sort Map in Java by value e.g. HashMap or Hashtable 
* throw NullPointerException if Map contains null values 
* It also sort values even if they are duplicates 
*/ 
public static <K extends Comparable,V extends Comparable> Map<K,V> sortByValues(Map<K,V> map){ 
    List<Map.Entry<K,V>> entries = new LinkedList<Map.Entry<K,V>>(map.entrySet()); 

    Collections.sort(entries, new Comparator<Map.Entry<K,V>>() { 

     @Override 
     public int compare(Entry<K, V> o1, Entry<K, V> o2) { 
      return o1.getValue().compareTo(o2.getValue()); 
      // to compare alphabetically case insensitive return this instead 
      // o1.getValue().toString().compareToIgnoreCase(o2.getValue().toString()); 
     } 
    }); 

    //LinkedHashMap will keep the keys in the order they are inserted 
    //which is currently sorted on natural ordering 
    Map<K,V> sortedMap = new LinkedHashMap<K,V>(); 

    for(Map.Entry<K,V> entry: entries){ 
     sortedMap.put(entry.getKey(), entry.getValue()); 
    } 

    return sortedMap; 
} 

llamar a este método, que utilizo:

Map<String, Integer> sorted = sortByValues(myOriginalHashMapObject); 

Leer más: http://javarevisited.blogspot.com/2012/12/how-to-sort-hashmap-java-by-key-and-value.html#ixzz2akXStsGj

Cuestiones relacionadas