Tengo este tipo de valores dentro de un mapa:
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1,"mark");
map.put(2,"1.1");
map.put(3,"google");
map.put(4,"12");
map.put(5,"2.2);
Necesito pedir este mapa, ordenando a ambos números y cadenas.
Lo que me pasa ahora es la siguiente (como se puede ver los números no están "ordenados", ya que son de cuerda)
1.1
12
2.2
google
mark
Lo que debería conseguir es:
1.1
2.2
12
google
mark
¿Cómo puedo hacerlo? Estoy un poco confundido.
Si realmente necesita un mapa se puede utilizar una LinkedHashMap
que se clasifica por orden de inserción. Para comparar los valores que puede crear su propio comparador:
Comparator<String> stringAndNumberComparator = (s1, s2) -> {
try {
return Double.valueOf(s1).compareTo(Double.valueOf(s2));
} catch (NumberFormatException e) {
return s1.compareTo(s2);
}
};
Ahora puede utilizar una corriente java para ordenar el conjunto de entrada de su mapa y recoger de nuevo a un LinkedHashMap
:
Map<Integer, String> sorted = map.entrySet().stream()
.sorted(Map.Entry.comparingByValue(stringAndNumberComparator))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (s1, s2) -> s1, LinkedHashMap::new));
Alternativamente, puede utilizar el comparador proporcionada en la respuesta de Karol Dowbecki con Map.Entry.comparingByValue()
.
El resultado será {2=1.1, 5=2.2, 4=12, 3=google, 1=mark}
;
Si sólo necesita una lista de los valores que sólo puede usar este otro:
List<String> sorted = map.values().stream()
.sorted(stringAndNumberComparator)
.collect(Collectors.toList());
El resultado en este caso será [1.1, 2.2, 12, google, mark]
.