2009-09-19 5 views

Répondre

14

Vous ne pouvez pas car le comparateur de TreeMap est exécuté uniquement sur les clés, par ex. voir ceci constructor.

Quoi qu'il en soit, vous pouvez utiliser plusieurs collections, utiliser TreeMap (ou plutôt HashMap) pour rechercher des éléments par des clés, et avoir un SortedSet pour itérer sur les valeurs.

0

Permuter les valeurs et les clés.

Plus sérieusement, veuillez indiquer le contexte que vous souhaitez atteindre. Peut-être qu'il suffit de trier après que le traitement soit fini.

+0

comment puis-je les échanger? –

+0

Il signifie que vous devriez utiliser tout ce que vous utilisez comme clé maintenant comme valeur, et vice versa. De cette façon, vous pouvez trier votre valeur, qui est maintenant la clé. – Jorn

+3

Cette approche est généralement mauvaise car la carte possède des clés uniques (par rapport à compareTo) mais pas nécessairement des valeurs uniques. Créer une nouvelle carte avec des clés échangées avec des valeurs peut vous donner un ensemble de données différent. – Buhb

1

Vous pouvez essayer de donner un comparateur qui compare les valeurs au lieu des clés lorsque vous créez le TreeMap.

final TreeMap<Integer,String> tree = new TreeMap<Integer,String>(); 
    tree.put(1, "1"); 
    tree.put(2, "2"); 
    tree.put(3, "3"); 
    tree.put(4, "4"); 

    final TreeMap<Integer,String> treeSortedByValues = new TreeMap<Integer,String>(new Comparator<Integer>() 
    { 
     public int compare(Integer o1, Integer o2) 
     { 
      return tree.get(o1).compareTo(tree.get(o2)); 
     } 
    }); 
    treeSortedByValues.putAll(tree); 

    for (Entry<Integer, String> e : treeSortedByValues.entrySet()) 
    { 
     System.out.println(e.getKey() + ": " + e.getValue()); 
    } 
+0

Comment le comparateur aura-t-il accès aux valeurs? – Zed

+1

Ce ne sera pas. Ce n'est pas possible avec TreeMap. – Jorn

+1

True, vous ne pouvez pas accéder aux valeurs de treemap dans le comparateur car le treemap n'est pas encore créé. Mais vous pouvez utiliser un treemap temporaire pour cela ... –

5

Apache Commons Collections a une TreeBidiMap:

Cette garantie de classe que la carte sera à la fois ordre croissant clé ordre et valeur ascendante, triées selon l'ordre naturel pour de la clé et classes de la valeur.

Il existe un port Java5-generic here.

+0

Le lien est rompu –

6

Google Collections fournit un TreeMultiMap.

Vous pouvez également utiliser deux collections. Qu'est-ce que vous essayez d'accomplir? Pouvez-vous expliquer vos cas d'utilisation?

23

Voici une solution:

public static <K, V extends Comparable<V>> Map<K, V> sortByValues(final Map<K, V> map) { 
    Comparator<K> valueComparator = new Comparator<K>() { 
     public int compare(K k1, K k2) { 
      int compare = map.get(k2).compareTo(map.get(k1)); 
      if (compare == 0) return 1; 
      else return compare; 
     } 
    }; 
    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator); 
    sortedByValues.putAll(map); 
    return sortedByValues; 
} 

Notez que la carte est triée de la valeur la plus élevée à la plus basse.

+0

Je reçois une exception stackoverflow avec cette méthode – superrache

+0

cela ne fonctionne pas!à moins que toutes les données sont dans la carte originale Map et vous n'avez jamais besoin de mettre de nouvelles valeurs – Leonmax

4

Essayez ci-dessous le code ça marche très bien pour moi. Vous pouvez choisir à la fois l'ordre ascendant et décroissant pour le tri.

package com.rais; 

import java.util.Collections; 
import java.util.Comparator; 
import java.util.HashMap; 
import java.util.LinkedHashMap; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.Map; 
import java.util.Map.Entry; 

public class SortMapByValue 
{ 
    public static boolean ASC = true; 
    public static boolean DESC = false; 

    public static void main(String[] args) 
    { 

     // Creating dummy unsorted map 
     Map<String, Integer> unsortMap = new HashMap<String, Integer>(); 
     unsortMap.put("B", 55); 
     unsortMap.put("A", 80); 
     unsortMap.put("D", 20); 
     unsortMap.put("C", 70); 

     System.out.println("Before sorting......"); 
     printMap(unsortMap); 

     System.out.println("After sorting ascending order......"); 
     Map<String, Integer> sortedMapAsc = sortByComparator(unsortMap, ASC); 
     printMap(sortedMapAsc); 


     System.out.println("After sorting descindeng order......"); 
     Map<String, Integer> sortedMapDesc = sortByComparator(unsortMap, DESC); 
     printMap(sortedMapDesc); 

    } 

    private static Map<String, Integer> sortByComparator(Map<String, Integer> unsortMap, final boolean order) 
    { 

     List<Entry<String, Integer>> list = new LinkedList<Entry<String, Integer>>(unsortMap.entrySet()); 

     // Sorting the list based on values 
     Collections.sort(list, new Comparator<Entry<String, Integer>>() 
     { 
      public int compare(Entry<String, Integer> o1, 
        Entry<String, Integer> o2) 
      { 
       if (order) 
       { 
        return o1.getValue().compareTo(o2.getValue()); 
       } 
       else 
       { 
        return o2.getValue().compareTo(o1.getValue()); 

       } 
      } 
     }); 

     // Maintaining insertion order with the help of LinkedList 
     Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>(); 
     for (Entry<String, Integer> entry : list) 
     { 
      sortedMap.put(entry.getKey(), entry.getValue()); 
     } 

     return sortedMap; 
    } 

    public static void printMap(Map<String, Integer> map) 
    { 
     for (Entry<String, Integer> entry : map.entrySet()) 
     { 
      System.out.println("Key : " + entry.getKey() + " Value : "+ entry.getValue()); 
     } 
    } 
} 
0

C'est Je l'ai fait ..

package Collections; 
import java.util.Comparator; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.Map.Entry; 
import java.util.TreeMap; 

class MyComparator implements Comparator<Object> { 

    public int compare(Object o1, Object o2) { 
     return (((Integer) o2).compareTo((Integer) o1)); 
    } 
} 

class MyComparator1 implements Comparator<Object> { 
    Map<Integer, String> map; 

    public MyComparator1(Map<Integer, String> m) { 
     this.map = m; 
    } 

    public int compare(Object o1, Object o2) { 
     return (((String) map.get(o1)).compareTo((String) map.get(o2))); 
    } 
} 

public class Map1 { 
    public static void main(String[] args) { 
     Map<Integer, String> hmap = new HashMap<Integer, String>(); 
     hmap.put(5, "Ashok"); 
     hmap.put(21, "Bhanu"); 
     hmap.put(7, "chaman"); 
     hmap.put(28, "dheeraj"); 
     hmap.put(761, "edison"); 
     hmap.put(1, "frank"); 
     hmap.put(-6, "gopal"); 
     hmap.put(78, "hari"); 
     System.out.println("Hash Map:" + hmap); 
     Map<Integer, String> tmap = new TreeMap<>(hmap); 
     System.out.println("Tree Map:" + tmap); 
     MyComparator comp = new MyComparator(); 
     Map<Integer, String> itmap = new TreeMap<>(comp); 
     itmap.putAll(hmap); 
     System.out.println("Tree Map Inreverse order:" + itmap); 
     Map<Integer, String> orderValuemap = new TreeMap<Integer, String>(new 
      MyComparator1(hmap)); 
      orderValuemap.putAll(hmap); 
      orderValuemap.put(22,"hello"); 
     for(Entry<Integer, String> mp:orderValuemap.entrySet()) 
      System.out.println("Value : "+mp.getValue()); 
    } 
} 
Questions connexes