2010-06-19 16 views
5

Duplicar posible:
How to sort a Map<Key, Value> on the values in Java?Ordenando un HashMap basado en el valor y luego la clave?

que tiene un HashMap del tipo:

HashMap<String, Integer> h = new HashMap<String, Integer>(); 

El HashMap contiene una lista de cadenas y el entero es un contador para el número de veces que se ha encontrado la Cadena Lo que me gustaría hacer es ordenar el HashMap basado en los Enteros, luego en el orden alfabético de las Cadenas.

Por el momento estoy manteniendo un registro de la mayor aparición de una palabra (variable llamada max) y la visualización de los valores de la siguiente manera:

public void print(){ 
    while(max > 0){ 
     for (String key : h.keySet()){ 
      if(h.get(key) == max){ 
       System.out.println(key + " " + h.get(key)); 
      } 
     } 
     max--; 
    } 
} 

Lo cual no ordenar los valores en orden alfabético, también se accede el HashMap max * h (tamaño) veces.

¿Cuál es la mejor solución?

+0

@krock buen encontrar. Sí, exactamente la misma pregunta. – cletus

Respuesta

3

Mire Google Guava libraries. Tiene un Multiset que hace el cálculo por usted y luego tiene la clase Ordering que simplifica la clasificación.

Todo lo que necesita hacer es poblar Multiset con sus cadenas. Mantendrá la frecuencia para ti. Luego puede ordenar esas cadenas usando Ordering.

1

Probablemente no sea la solución más elegante, pero ¿qué tal esto?

//TreeSet with reversed natural ordering (big integers first) 
Map<Integer, Set<String>> h = 
    new TreeMap<Integer, Set<String>>(Collections.reverseOrder()); 
//and use TreeSet for the set... 
// ...  
// 
for(Map.Entry<Integer,Set<String>> entry : h.entrySet()){ 
    for(String str : entry.getValue()){ 
     System.out.println(str + " has occured " + entry.getKey() + " times."); 
    } 
} 
+1

'-1 * o1.compareTo (o2)' tiene errores. Considere el caso donde 'compareTo' devuelve' Integer.MIN_VALUE'. –

+0

@Stephen: ¡Gracias por señalar! –

+0

En realidad, no debería haber escrito mi propio código para invertir el orden natural: P Sustituyendo con el método 'Collections.reverseOrder()' .. –

8

Aquí hay una Comparator que ordena Map.Entry objetos con Comparable claves y valores:

public class ValueThenKeyComparator<K extends Comparable<? super K>, 
            V extends Comparable<? super V>> 
    implements Comparator<Map.Entry<K, V>> { 

    public int compare(Map.Entry<K, V> a, Map.Entry<K, V> b) { 
     int cmp1 = a.getValue().compareTo(b.getValue()); 
     if (cmp1 != 0) { 
      return cmp1; 
     } else { 
      return a.getKey().compareTo(b.getKey()); 
     } 
    } 

} 

que había puesto todas las entradas de mapa en una lista y luego ordenar que:

List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(h.entrySet()); 
Collections.sort(list, new ValueThenKeyComparator<String, Integer>()); 
+0

Casi, supongo porque porque de esta manera las palabras con menos ocurrencias son las primeras .. –

-2

puede usar la interfaz SortedMap para ordenar su HashMap. Es muy fácil: clasificación automática. Consulte http://java.sun.com/j2se/1.4.2/docs/api/java/util/SortedMap.html. No incluí ningún código aquí, pero si lo necesita, solo agregue un comentario. Te daré un código de muestra.

+1

- 1, SortedMap ordena por clave, en lugar de por valor – whiskeysierra

+0

Un mapa que garantiza además que estará en orden ascendente, ordenado de acuerdo con el orden natural de sus claves (ver la interfaz Comparable), o por un comparador provisto en el mapa ordenado tiempo de creación – Vishal

Cuestiones relacionadas