Maison >Java >javaDidacticiel >Une brève discussion sur le tri par valeur de la carte Java (Tri de la carte par valeur)

Une brève discussion sur le tri par valeur de la carte Java (Tri de la carte par valeur)

高洛峰
高洛峰original
2017-01-19 10:54:331676parcourir

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().

Méthode 2 :

Vous pouvez également utiliser le code suivant pour trier par valeur :

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]

De plus, le tri de la carte par valeur est implémenté dans Groovy. Bien sûr, l'essence est la même, mais c'est très simple :


Utilisez la méthode de tri de la carte. en groovy (nécessite groovy 1.6) ,

def result = map.sort(){ a, b ->
      b.value.compareTo(a.value)
    }

Par exemple :


["a":3,"b":1,"c ":4,"d": 2].sort{ a,b -> a.value - b.value }


Le résultat est : [b:1, d:2, a :3, c:4]


C'est similaire en Python :

h = {"a":2,"b":1,"c":3}
i = h.items() // i = [(&#39;a&#39;, 2), (&#39;c&#39;, 3), (&#39;b&#39;, 1)]
i.sort(lambda (k1,v1),(k2,v2): cmp(v2,v1) ) // i = [(&#39;c&#39;, 3), (&#39;a&#39;, 2), (&#39;b&#39;, 1)]

L'article ci-dessus parle brièvement du tri par valeur de Java (Map sort par valeur), que je partage avec vous. L'intégralité du contenu est ici, j'espère qu'il pourra donner une référence à chacun, et j'espère aussi que tout le monde soutiendra le site Web PHP chinois.

Pour plus d'articles sur le tri des cartes par valeur en Java, veuillez faire attention au site Web PHP chinois !


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn