example - En Java, clasifique el hash map por su key.length()
map get key java (6)
tengo un hashmap como este:
HashMap<String,Integer> map = new HashMap<String,Integer>();
map.put("java",4);
map.put("go",2);
map.put("objective-c",11);
map.put("c#",2);
ahora quiero ordenar este mapa por su longitud de clave, si la longitud de dos teclas es igual (por ejemplo, ir y c # ambas de longitud 2), luego ordenadas por orden de alphba. así que el resultado que espero obtener es algo así como:
resultado impreso: objetivo-c, 11 java, 4 c #, 2 go, 2
aquí está mi propio attamp, pero no funciona en absoluto ...
HashMap<String,Integer> map = new HashMap<String,Integer>();
map.put("java",4);
map.put("go",2);
map.put("objective-c",11);
map.put("c#",2);
Map<String,Integer> treeMap = new TreeMap<String, Integer>(
new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.length().compareTo(s2.length());
}
}
);
de hecho, el método ''compareTo'' aparece como rojo (no se puede compilar) ... por favor, alguien me ayude con algún ejemplo de código ... soy un poco confuso con cómo usar la clase de comparación para personalizar el objeto de comparación ...
Si usa TreeMap no es obligatorio
Explicación : defina un Comaprator
, y el siguiente paso, defina una lista para que podamos agregar todas las entradas del mapa en una lista. Al final, ordena la lista por el Comaprator
definido
Código :
Comparator<Map.Entry<String,Integer>> byMapValues =
(Map.Entry<String,Integer> left, Map.Entry<String,Integer> right) ->left.getValue().compareTo(right.getValue());
List<Map.Entry<String,Integer>> list = new ArrayList<>();
list.addAll(map.entrySet());
Collections.sort(list, byMapValues);
list.forEach( i -> System.out.println(i));
Salida :
c#=2
go=2
java=4
objective-c=11
Nota: obtener ordenados por número
si es necesario hacer una comparación basada en la clave, se puede usar la siguiente línea.
Comparator<Map.Entry<String,Integer>> byMapKeys =
(Map.Entry<String,Integer> left, Map.Entry<String,Integer> right) -> left.getKey().compareTo(right.getKey());
El Comparador debería ser:
new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
}
El compilador se queja porque no puede invocar compareTo
en un int
. La forma correcta de ordenar el mapa es la siguiente:
Map<String, Integer> treeMap = new TreeMap<String, Integer>(
new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
if (s1.length() > s2.length()) {
return -1;
} else if (s1.length() < s2.length()) {
return 1;
} else {
return s1.compareTo(s2);
}
}
});
Las primeras dos condiciones comparan las longitudes de las dos String
y devuelven un número positivo o negativo en consecuencia. La tercera condición compararía la String
lexicográfica si sus longitudes son iguales.
porque length()
no define compareTo
método compareTo
es por eso que ves el error. Para corregirlo, use Integer.compare(s1.length(), s2.length());
código actualizado a continuación
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class Test {
public static void main(String[] args) {
HashMap<String,Integer> map = new HashMap<String,Integer>();
map.put("java",4);
map.put("go",2);
map.put("objective-c",11);
map.put("c#",2);
Map<String,Integer> treeMap = new TreeMap<String, Integer>(
new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
}
);
treeMap.putAll(map);
System.out.println(treeMap);
}
}
public int compare(String o1, String o2) {
return o1.length() == o2.length() ? o1.compareTo(o2) : o1.length() - o2.length();
}
Llama a String#length()
, que devuelve una primitiva int
. Necesita el método estático Integer.compare(int,int)
. Si tienes Java 8, puedes ahorrarte un montón de tipeo:
Map<String,Integer> treeMap = new TreeMap<>(
Comparator.comparingInt(String::length)
.thenComparing(Function.identity()));