J'ai cette HashMap
que je dois imprimer dans l'ordre croissant en fonction duvaleursqu'il contient (pas les touches).
Mais l'ordre dans lequel je l'imprime est apparemment aléatoire.
Quelle est la meilleure façon de l’imprimer dansordre de valeur croissant?
Map<String, String> codes = new HashMap<String, String>();
codes.put("A1", "Aania");
codes.put("X1", "Abatha");
codes.put("C1", "Acathan");
codes.put("S1", "Adreenas");
En d'autres termes, l'exemple ci-dessus devrait être imprimé comme ceci:
A1, Aania
X1, Abatha
C1, Acathan
S1, Adreenas
Vous ne pourrez pas faire cela à partir de la classe HashMap uniquement.
Je prendrais le Map<String, String> codes
, construirais une mappe inversée de TreeMap<String, String> reversedMap
où vous mapperiez les valeurs de la mappe codes
aux clés (pour que la mappe originale ait un mappage un à un de clé à valeur). Étant donné que TreeMap fournit des itérateurs qui renvoient les entrées dans l'ordre croissant des clés, vous obtiendrez la combinaison valeur/clé de la première carte dans l'ordre (trié par valeurs) de votre choix.
Map<String, String> reversedMap = new TreeMap<String, String>(codes);
//then you just access the reversedMap however you like...
for (Map.Entry entry : reversedMap.entrySet()) {
System.out.println(entry.getKey() + ", " + entry.getValue());
}
Plusieurs bibliothèques de collections (commons-collections, Google Collections, etc.) ont des implémentations de carte bidirectionnelles similaires.
Vous devrez faire une liste des clés, les trier en fonction des valeurs correspondantes, puis parcourir les clés triées.
Map<String, String> map = getMyMap();
List<String> keys = new ArrayList<String>(map.keySet());
Collections.sort(keys, someComparator);
for (String key: keys) {
System.out.println(key + ": " + map.get(key));
}
En ce qui concerne quoi utiliser pour someComparator
, voici quelques routines génériques pratiques pour la création de comparateurs que je trouve souvent utiles. Le premier trie les valeurs en fonction de leur ordre naturel, et le second vous permet de spécifier n'importe quel comparateur arbitraire pour trier les valeurs:
public static <K, V extends Comparable<? super V>>
Comparator<K> mapValueComparator(final Map<K, V> map) {
return new Comparator<K>() {
public int compare(K key1, K key2) {
return map.get(key1).compareTo(map.get(key2));
}
};
}
public static <K, V>
Comparator<K> mapValueComparator(final Map<K, V> map,
final Comparator<V> comparator) {
return new Comparator<K>() {
public int compare(K key1, K key2) {
return comparator.compare(map.get(key1), map.get(key2));
}
};
}
Il est temps d'ajouter quelques lambdas:
codes.entrySet()
.stream()
.sorted(Comparator.comparing(Map.Entry::getValue))
.forEach(System.out::println);
il vous suffit d'utiliser:
Map<>.toString().replace("]","\n");
et remplace le crochet final de chaque clé = valeur définie par une nouvelle ligne.
la boucle for de pour (entrée Map.Entry: codes.entrySet()
) n'a pas fonctionné pour moi. Utilisez Itérateur à la place.
Iterator<Map.Entry<String, String>> i = codes.entrySet().iterator();
while(i.hasNext()){
String key = i.next().getKey();
System.out.println(key+", "+codes.get(key));
}
Java 8
map.entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(System.out::println);
TreeMap<String,String>
HashMap
avec la valeur comme clé.Si les valeurs ne sont pas uniques, vous aurez besoin d’une liste en deuxième position.
Vous pouvez utiliser une liste du jeu d'entrées plutôt que le jeu de clés. Il s'agit d'un choix plus naturel étant donné que vous effectuez un tri en fonction de la valeur. Cela évite beaucoup de recherches inutiles dans le tri et l'impression des entrées.
Map<String, String> map = ...
List<Map.Entry<String, String>> listOfEntries = new ArrayList<Map.Entry<String, String>>(map.entrySet());
Collections.sort(listOfEntries, new SortByValueComparator());
for(Map.Entry<String, String> entry: listOfEntries)
System.out.println(entry);
static class SortByValueComparator implements Comparator<Map.Entry<String, String>> {
public int compareTo(Map.Entry<String, String> e1, Map.Entry<String, String> e2) {
return e1.getValue().compateTo(e2.getValue());
}
}
je pense que le code le plus simple et le plus court est le suivant:
public void listPrinter(LinkedHashMap<String, String> caseList) {
for(Entry entry:caseList.entrySet()) {
System.out.println("K: \t"+entry.getKey()+", V: \t"+entry.getValue());
}
}