2009-09-19 97 views

Respuesta

14

No se puede, ya que el comparador TreeMap se ejecuta solo con las teclas, p. vea esto constructor.

De todos modos, puede usar varias Colecciones, usar TreeMap (o más bien HashMap) para buscar elementos por claves, y tener SortedSet para repetir los valores.

0

Cambie los valores y las claves.

Más en serio, por favor proporcione un contexto de lo que quiere lograr. Tal vez sea suficiente para ordenar después de que haya terminado otro procesamiento.

+0

¿cómo puedo intercambiarlos? –

+0

Quiere decir que debe usar lo que esté usando como clave ahora como el valor, y viceversa. De esta forma puede ordenar su valor, que ahora es la clave. – Jorn

+3

Este es generalmente un enfoque pobre ya que el mapa tiene claves únicas (con respecto a compareTo) pero no necesariamente valores únicos. Crear un nuevo mapa con las claves intercambiadas con valores puede proporcionarle un conjunto de datos diferente. – Buhb

1

Puede intentar dar un Comparador que compare los valores en lugar de las claves al crear el Árbol de mapa.

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

¿Cómo obtendrá acceso el comparador a los valores? – Zed

+1

No lo hará. Esto no es posible con TreeMap. – Jorn

+1

Es cierto que no puede acceder a los valores de treemap en el comparador ya que el treemap no se ha creado todavía. Pero puede usar un treemap temporal para eso ... –

5

Apache Commons Collections tiene un TreeBidiMap:

Esto garantiza la clase que el mapa será tanto para y el valor ascendente orden de las teclas ascendente, ordenados de acuerdo con el orden natural de la clave de y clases de valor.

Hay un puerto genérico Java5 here.

+0

El enlace está roto –

6

Google Collections proporciona un TreeMultiMap.

También podría usar dos colecciones. ¿Qué está tratando de lograr? ¿Puedes explicar tus casos de uso?

23

Aquí es una solución:

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

Tenga en cuenta que el mapa se ordena desde el valor más alto al más bajo.

+0

Estoy obteniendo una excepción de stackoverflow con este método – superrache

+0

¡esto en realidad no funciona!a menos que todos los datos estén en el mapa original 'Map ' y nunca tenga que poner nuevos valores – Leonmax

4

Probar debajo de código funciona bien para mí. Puede elegir tanto el orden ascendente como el descendente para la clasificación.

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

Eso es que he hecho esto ..

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()); 
    } 
} 
Cuestiones relacionadas