Map est une collection de paires clé-valeur, également appelée dictionnaire ou tableau associatif, etc. C'est l'une des structures de données les plus courantes. Comment trier une carte par valeur en Java ? Cela semble simple, mais ce n’est pas facile !
Par exemple, la clé dans la carte est de type String, représentant un mot, et la valeur est de type int, représentant le nombre de fois que le mot apparaît. Nous voulons maintenant trier par le nombre de fois. le mot apparaît :
Map map = new TreeMap(); map.put("me", 1000); map.put("and", 4000); map.put("you", 3000); map.put("food", 10000); map.put("hungry", 5000); map.put("later", 6000);
Le résultat du tri par valeur doit être :
key value me 1000 you 3000 and 4000 hungry 5000 later 6000 food 10000
Tout d'abord, la structure SortedMap ne peut pas être utilisé, car SortedMap est une carte triée par clé, pas par carte triée par valeur, ce que nous voulons, c'est une carte triée par valeur.
Ne pourriez-vous pas faire cela avec une SortedMap ?
Non, car les cartes sont triées par leurs clés.
Méthode 1 :
Le code Java suivant :
import java.util.Iterator; import java.util.Set; import java.util.TreeSet; public class Main { public static void main(String[] args) { Set set = new TreeSet(); set.add(new Pair("me", "1000")); set.add(new Pair("and", "4000")); set.add(new Pair("you", "3000")); set.add(new Pair("food", "10000")); set.add(new Pair("hungry", "5000")); set.add(new Pair("later", "6000")); set.add(new Pair("myself", "1000")); for (Iterator i = set.iterator(); i.hasNext();) System.out.println(i.next()); } } class Pair implements Comparable { private final String name; private final int number; public Pair(String name, int number) { this.name = name; this.number = number; } public Pair(String name, String number) throws NumberFormatException { this.name = name; this.number = Integer.parseInt(number); } public int compareTo(Object o) { if (o instanceof Pair) { int cmp = Double.compare(number, ((Pair) o).number); if (cmp != 0) { return cmp; } return name.compareTo(((Pair) o).name); } throw new ClassCastException("Cannot compare Pair with " + o.getClass().getName()); } public String toString() { return name + ' ' + number; } }
Code C similaire :
typedef pair<string, int> PAIR; int cmp(const PAIR& x, const PAIR& y) { return x.second > y.second; } map<string,int> m; vector<PAIR> vec; for (map<wstring,int>::iterator curr = m.begin(); curr != m.end(); ++curr) { vec.push_back(make_pair(curr->first, curr->second)); } sort(vec.begin(), vec.end(), cmp);
La signification essentielle de la méthode ci-dessus est d'encapsuler les paires clé-valeur (Map.Entry) dans la structure Map dans une classe personnalisée (structure), ou d'utiliser directement la classe Map.Entry. La classe personnalisée sait comment elle doit être triée, c'est-à-dire triée par valeur, plus précisément, elle implémente l'interface Comparable ou construit un objet Comparator pour elle-même, puis utilise un ensemble ordonné (SortedSet, TreeSet est une implémentation de SortedSet) au lieu de. une structure Map, de sorte que l'objectif du tri par valeur dans Map soit atteint. C'est-à-dire qu'au lieu d'utiliser Map, traitez Map.Entry comme un objet, le problème devient donc d'implémenter une collection ordonnée de l'objet ou de trier la collection de l'objet. Vous pouvez soit utiliser un SortedSet, afin qu'il soit naturellement ordonné une fois l'insertion terminée, soit utiliser une liste ou un tableau, puis le trier (Collections.sort() ou Arrays.sort()).
Encapsulez les informations dans sa propre classe. Soit implémentez
Comparable et écrivez des règles pour l'ordre naturel, soit écrivez un
Comparateur basé sur vos critères. >collection, ou utilisez la méthode Collections.sort().
public static Map sortByValue(Map map) { List list = new LinkedList(map.entrySet()); Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { return ((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } }); Map result = new LinkedHashMap(); for (Iterator it = list.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); result.put(entry.getKey(), entry.getValue()); } return result; } public static Map sortByValue(Map map, final boolean reverse) { List list = new LinkedList(map.entrySet()); Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { if (reverse) { return -((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } return ((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } }); Map result = new LinkedHashMap(); for (Iterator it = list.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); result.put(entry.getKey(), entry.getValue()); } return result; } Map map = new HashMap(); map.put("a", 4); map.put("b", 1); map.put("c", 3); map.put("d", 2); Map sorted = sortByValue(map); System.out.println(sorted); // output : {b=1, d=2, c=3, a=4} 或者还可以这样: Map map = new HashMap(); map.put("a", 4); map.put("b", 1); map.put("c", 3); map.put("d", 2); Set<Map.Entry<String, Integer>> treeSet = new TreeSet<Map.Entry<String, Integer>>( new Comparator<Map.Entry<String, Integer>>() { public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { Integer d1 = o1.getValue(); Integer d2 = o2.getValue(); int r = d2.compareTo(d1); if (r != 0) return r; else return o2.getKey().compareTo(o1.getKey()); } }); treeSet.addAll(map.entrySet()); System.out.println(treeSet); // output : [a=4, c=3, d=2, b=1]
def result = map.sort(){ a, b -> b.value.compareTo(a.value) }
h = {"a":2,"b":1,"c":3} i = h.items() // i = [('a', 2), ('c', 3), ('b', 1)] i.sort(lambda (k1,v1),(k2,v2): cmp(v2,v1) ) // i = [('c', 3), ('a', 2), ('b', 1)]