Cómo ordenar un Map en Java

La clase Hashmap en Java proporciona una forma conveniente de almacenar y recuperar pares clave-valor. Si bien los hashmaps están intrínsecamente desordenados, hay momentos en los que es posible que deseemos ordenar las entradas en función de las claves o los valores.

En este artículo, exploraremos dos enfoques para ordenar un hashmap de Java: ordenar por clave usando un TreeMap y ordenar por valor usando un Comparator. Al final de este artículo, comprenderá mejor cómo ordenar un Hashmap en Java y cómo elegir el enfoque correcto en función de su caso de uso específico.

Ordenar un Map en Java por key

La forma más sencilla de ordenar un Map por key es utilizando la clase java.util.TreeMap. De acuerdo a la documentación oficial, un TreeMap es una implementación de la interfaz NavigableMap basada en árbol rojo-negro. TreeMap mantiene sus ítems ordenados de acuerdo al orden natural de las keys de dichos ítems. También permite generar un ordenamiento personalizado asignando un Comparator que implemente el orden deseado.

En este ejemplo:

  • Se crea un HashMap y se asignan ítems de forma que las keys no ingresen en orden.
  • Al imprimir el HashMap los ítems aparecen en orden aleatorio.
  • Se instancia un TreeMap a partir del HashMap creado anteriormente.
  • Al imprimir el TreeMap los ítems se muestran ordenados de forma ascendente por su key correspondiente.
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class OrdenarMapEjemplo1 {

	public static void main(String[] args) {
		Map<String, String> capitalmap = new HashMap<String, String>();
		capitalmap.put("D", "Viena");
		capitalmap.put("E", "Bruselas");
		capitalmap.put("B", "Copenhague");
		capitalmap.put("A", "Madrid");
		capitalmap.put("C", "Helsinki");
		capitalmap.put("Z", "París");
		capitalmap.put("X", "Budapest");
		capitalmap.put("W", "Dublin");
		capitalmap.put("Y", "Roma");
		capitalmap.put("Q", "Luxemburgo");
		capitalmap.put("R", "Mónaco");
		capitalmap.put("S", "Oslo");
		
		System.out.println("-> HashMap sin ordenar:");
		
		for (Map.Entry<String, String> e : capitalmap.entrySet()) {
			System.out.println("-> key: " + e.getKey() + " - value: " + e.getValue());
		}
		
		Map<String, String> sortedmap = new TreeMap<String, String>(capitalmap);
		
		System.out.println("\n-> TreeMap ordenado por key:");
		
		for (Map.Entry<String, String> e : sortedmap.entrySet()) {
			System.out.println("-> key: " + e.getKey() + " - value: " + e.getValue());
		}
	}
}

Salida:

-> HashMap sin ordenar:
-> key: A - value: Madrid
-> key: Q - value: Luxemburgo
-> key: B - value: Copenhague
-> key: R - value: Mónaco
-> key: C - value: Helsinki
-> key: S - value: Oslo
-> key: D - value: Viena
-> key: E - value: Bruselas
-> key: W - value: Dublin
-> key: X - value: Budapest
-> key: Y - value: Roma
-> key: Z - value: París

-> TreeMap ordenado por key:
-> key: A - value: Madrid
-> key: B - value: Copenhague
-> key: C - value: Helsinki
-> key: D - value: Viena
-> key: E - value: Bruselas
-> key: Q - value: Luxemburgo
-> key: R - value: Mónaco
-> key: S - value: Oslo
-> key: W - value: Dublin
-> key: X - value: Budapest
-> key: Y - value: Roma
-> key: Z - value: París

Ordenar un Map en Java por valor

Para ordenar por value será necesario convertir el EntrySet del Map en un List y aplicar el método Collections.sort(List<T>, Comparator<? super T>). Además, será necesario implementar un Comparator con el criterio a ser utilizado en el ordenamiento.

En este ejemplo:

  • Se crea un HashMap y se ingresan sus ítems observando que las keys no sigan un orden en particular.
  • Si se imprime el HashMap creado la salida muestra que las keys siguen un orden aleatorio.
  • Se invoca Collections.sort(List, Comparator) pasando los siguientes parámetros:
    • Una List creada a partir de los ítems del HashMap.
    • Un Comparator implementando el método compare(T o1, T o2) de forma que el ordenamiento sea ascendente por value.
  • Si se imprime el nuevo Map la salida los mostrará ordenados por los nombre de ciudades ingresados en el value de cada ítem.
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class OrdenarMapEjemplo2 {

	public static void main(String[] args) {
		Map<String, String> capitalmap = new HashMap<String, String>();
		capitalmap.put("D", "Viena");
		capitalmap.put("E", "Bruselas");
		capitalmap.put("B", "Copenhague");
		capitalmap.put("A", "Madrid");
		capitalmap.put("C", "Helsinki");
		capitalmap.put("Z", "París");
		capitalmap.put("X", "Budapest");
		capitalmap.put("W", "Dublin");
		capitalmap.put("Y", "Roma");
		capitalmap.put("Q", "Luxemburgo");
		capitalmap.put("R", "Mónaco");
		capitalmap.put("S", "Oslo");
		
		System.out.println("-> Map sin ordenar:");
		capitalmap.forEach((k, v) -> System.out.println("-> key: " + k + " - value: " + v));
		
		List<Map.Entry> l = 
				Arrays.asList(capitalmap.entrySet().toArray(new Map.Entry[0]));
		
		Collections.sort(l, new Comparator<Map.Entry>(){
			@Override
			public int compare(Entry entry1, Entry entry2) {
				return entry1.getValue().toString().compareTo(entry2.getValue().toString());
			}
		});
		
		Map<String, String> lmap = new LinkedHashMap<String, String>();
		
		for (Entry<String, String> e : l) {
			lmap.put(e.getKey(), e.getValue());
		}
		
		System.out.println("\n-> Map ordenado por value:");
		lmap.forEach((k, v) -> System.out.println("-> key: " + k + " - value: " + v));
	}
}

Salida:

-> Map sin ordenar:
-> key: A - value: Madrid
-> key: Q - value: Luxemburgo
-> key: B - value: Copenhague
-> key: R - value: Mónaco
-> key: C - value: Helsinki
-> key: S - value: Oslo
-> key: D - value: Viena
-> key: E - value: Bruselas
-> key: W - value: Dublin
-> key: X - value: Budapest
-> key: Y - value: Roma
-> key: Z - value: París

-> Map ordenado por value:
-> key: E - value: Bruselas
-> key: X - value: Budapest
-> key: B - value: Copenhague
-> key: W - value: Dublin
-> key: C - value: Helsinki
-> key: Q - value: Luxemburgo
-> key: A - value: Madrid
-> key: R - value: Mónaco
-> key: S - value: Oslo
-> key: Z - value: París
-> key: Y - value: Roma
-> key: D - value: Viena

Conclusión

En este artículo hemos visto que en Java los HashMaps no mantienen ningún orden. Con las técnicas que hemos visto puede ordenar fácilmente un HashMap de Java y manipular su orden de acuerdo con sus requisitos.


Te puede interesar:

Filtrar Map a List en Java

En este artículo explicamos diferentes formas de filtrar los valores de un map y pasarlos a una List en Java.

Seguir leyendo →

Cómo inicializar un Map en Java

En este artículo se explican diferentes formas de inicializar un java.util.Map en diferentes versiones de Java,

Seguir leyendo →

Palabras reservadas en Java

Las palabras reservadas en Java son un componente crucial de la sintaxis del lenguaje para formar los bloques básicos del lenguaje.

Seguir leyendo →