2009-09-19 21 views

Odpowiedz

14

Nie można, ponieważ komparator drzewa jest porównywany tylko z kluczami, np. zobacz to constructor.

W każdym razie możesz użyć wielu kolekcji, użyć TreeMap (lub raczej HashMap) do wyszukiwania elementów po klawiszach i mieć SortedSet do iteracji wartości.

0

Zamień wartości i klucze.

Co ważniejsze, proszę podać kontekst, co chcesz osiągnąć. Może wystarczy sortować po zakończeniu przetwarzania.

+0

Jak mogę je wymienić? –

+0

Oznacza to, że powinieneś teraz używać wszystkiego, co używasz jako klucza, i na odwrót. W ten sposób możesz sortować swoją wartość, która jest teraz kluczem. – Jorn

+3

Jest to ogólnie słabe podejście, ponieważ mapa ma unikalne klucze (w odniesieniu do compareTo), ale niekoniecznie wartości unikalne. Utwórz nową mapę z kluczami zamienionymi na wartości, które mogą dać ci inny zestaw danych. – Buhb

1

Możesz spróbować podać Komparator porównujący wartości zamiast kluczy podczas tworzenia 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

W jaki sposób komparator uzyska dostęp do wartości? – Zed

+1

Nie będzie. Nie jest to możliwe z mapą drzewa. – Jorn

+1

Prawda, nie można uzyskać dostępu do wartości treemap w komparatorze, ponieważ treemap nie jest jeszcze utworzona. Ale możesz użyć tymczasowej treemap dla tego ... –

5

Apache Commons Collections ma TreeBidiMap:

To gwarantuje Klasa że mapa będzie zarówno wznoszącego kluczowego zamówienia i wartości rosnącej kolejności, sortowane według naturalnego porządku dla osób klucz i klasy wartości.

Jest to port generyczny Java5 here.

+0

Link jest zepsuty –

6

Google Kolekcje zapewnia TreeMultiMap.

Można również użyć dwóch kolekcji. Co próbujesz osiągnąć? Czy możesz wyjaśnić swoje przypadki użycia?

23

Oto rozwiązanie:

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

Należy zauważyć, że mapa jest posortowane od największej wartości do najmniejszej.

+0

Otrzymuję wyjątek stackoverflow z tą metodą – superrache

+0

to faktycznie nie działa!chyba że wszystkie dane znajdują się na oryginalnej mapie 'Map ' i nigdy nie musisz wstawiać nowych wartości – Leonmax

4

Spróbuj poniżej kodu działa mi dobrze. Możesz wybrać zarówno sortowanie według rosnącej, jak i malejącej kolejności.

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

To się I zostało to zrobione ..

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()); 
    } 
} 
Powiązane problemy