2009-09-19 20 views

risposta

14

Non è possibile poiché il comparatore di TreeMap viene eseguito solo contro le chiavi, ad es. vedi questo constructor.

In ogni caso, è possibile utilizzare più raccolte, utilizzare la TreeMap (o piuttosto HashMap) per cercare elementi per chiavi e disporre di un SortedSet per iterare sui valori.

0

Valori di scambio e chiavi.

Più seriamente, si prega di fornire un contesto che cosa si vuole raggiungere. Forse è abbastanza per ordinare dopo che l'altra elaborazione è finita.

+0

come posso scambiarli? –

+0

Significa che dovresti usare quello che stai usando come chiave ora come valore, e viceversa. In questo modo puoi ordinare il tuo valore, che ora è la chiave. – Jorn

+3

Questo è generalmente un approccio scarso poiché la mappa ha chiavi univoche (rispetto a compareTo) ma non necessariamente valori univoci. Crea una nuova mappa con i tasti scambiati con valori potrebbe darti un set di dati diverso. – Buhb

1

Si può provare a dare un comparatore che confronta i valori anziché i tasti quando si crea la 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

In che modo il comparatore avrà accesso ai valori? – Zed

+1

Non lo farà. Questo non è possibile con TreeMap. – Jorn

+1

Vero, non è possibile accedere ai valori della mappa tre nel comparatore poiché la mappa non è ancora stata creata. Ma è possibile utilizzare una treemap temporanea per questo ... –

5

Apache Commons Collections ha un TreeBidiMap:

Questo garantisce di classe che la mappa sarà sia in ordine e il valore crescente chiave ascendente, ordinati secondo l'ordine naturale per la chiave del e classi del valore.

C'è una porta Java5-generics di esso here.

+0

Il collegamento è rotto –

6

Google Collections fornisce uno TreeMultiMap.

È anche possibile utilizzare due raccolte. Cosa stai cercando di realizzare? Puoi spiegare i tuoi casi d'uso?

23

Ecco una soluzione:

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; 
} 

notare che la mappa è ordinato dal valore più alto al più basso.

+0

Ricevo un'eccezione StackOverflow con questo metodo – superrache

+0

in realtà non funziona!a meno che tutti i dati non siano nella mappa originale 'Mappa ' e non sia mai necessario inserire nuovi valori – Leonmax

4

Provare sotto il codice funziona bene per me. È possibile scegliere sia l'ordine crescente che quello decrescente per l'ordinamento.

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

Ecco ho fatto ..

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()); 
    } 
} 
Problemi correlati