web-dev-qa-db-fra.com

Comment imprimer le contenu d'un HashMap <String, String> dans l'ordre croissant en fonction de ses valeurs?

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
31
Carlsberg

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.

39
matt b

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));
        }
    };
}
11
Sean

Il est temps d'ajouter quelques lambdas:

codes.entrySet()
    .stream()
    .sorted(Comparator.comparing(Map.Entry::getValue))
    .forEach(System.out::println);
6
Vladimir

il vous suffit d'utiliser: 

 Map<>.toString().replace("]","\n");

et remplace le crochet final de chaque clé = valeur définie par une nouvelle ligne.

5
ole scharling

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));
}
5
psun

Java 8

map.entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(System.out::println);
3
bluehallu
  1. Créer un TreeMap<String,String>
  2. Ajoutez chacune des entrées HashMap avec la valeur comme clé.
  3. itérer la TreeMap

Si les valeurs ne sont pas uniques, vous aurez besoin d’une liste en deuxième position.

2
bmargulies

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());
   }
}
1
Peter Lawrey

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());
    }
}
0
TheTeslaa