Esta es una pregunta bastante frecuente en Java 8. Desde que los streams fueron agregados en Java 8, esto se ha convertido en una forma elegante y funcional.
Por ejemplo, considere que se tiene un Map de palabras con sus respectivas cuentas en un documento en particular como se muestra a continuación:
1 2 3 4 5 6 7 | final Map<String, Integer> wordCounts = new HashMap<>(); wordCounts.put("USA", 100); wordCounts.put("jobs", 200); wordCounts.put("software", 50); wordCounts.put("technology", 70); wordCounts.put("opportunity", 200); |
Ahora, si se tiene que ordenar esta lista por el valor en forma ascendente, es tan simple como el código a continuación:
1 2 3 4 | final Map<String, Integer> sortedByCount = wordCounts.entrySet() .stream() .sorted(Map.Entry.comparingByValue()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); |
En este caso se esta utilizando LinkedHashMap para almacenar el resultado ordenado de los elementos en el map resultante.
Las ventajas de este acercamiento es:
- Esto no modifica la data original de wordCounts, haciendolo más adecuado si se utiliza hilos.
- Es más fácil de leer.
Si se quiere ordenar el map en orden descendente, solo se tiene que especificar que la comparación será en orden reverso:
1 2 3 4 | final Map<String, Integer> sortedByCount = wordCounts.entrySet() .stream() .sorted((Map.Entry.<String, Integer>comparingByValue().reversed())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); |
El programa completo para el ordenamiento en orden reverso es:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class SortMapByValueExample { public static Map<String, Integer> sortByValue(final Map<String, Integer> wordCounts) { return wordCounts.entrySet() .stream() .sorted((Map.Entry.<String, Integer>comparingByValue().reversed())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); } public static void main(String[] args) { final Map<String, Integer> wordCounts = new HashMap<>(); wordCounts.put("USA", 100); wordCounts.put("jobs", 200); wordCounts.put("software", 50); wordCounts.put("technology", 70); wordCounts.put("opportunity", 200); final Map<String, Integer> sortedByCount = sortByValue(wordCounts); System.out.println(sortedByCount); } } |
La salida de este programa es:
1 | {jobs=200, opportunity=200, USA=100, technology=70, software=50} |
Se puede observar que el método sorted() toma a Comparator como argumento, haciendo posible ordenar el map con cualquier tipo de valor. Por ejemplo, el siguiente ejemplo se puede ordenar con el Comparator de la siguiente forma:
1 2 3 4 5 6 | public static Map<String, Integer> sortByValue(final Map<String, Integer> wordCounts) { return wordCounts.entrySet() .stream() .sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); } |
Este artículo se encuentra basado en How to Sort a Map by Value in Java 8.