2012-02-06 121 views

回答

2

如果你知道你的值是唯一的,你可以使用番石榴的BiMap(双向映射)来存储数据。创建一个HashBiMap,你会你HashMap,然后创建一个从它的逆一个新TreeMap

new TreeMap<>(biMap.inverse()); 

该地图然后由值进行排序。请记住,您正在考虑的“键”和“值”将被交换。

如果你的值不是唯一的,你可以创建一个反转的多图。多重映射本质上是从每个键到一个或多个值的映射。通常通过制作从键到列表的映射来实现。你不必这样做,因为谷歌为你做了。只需从您现有的地图创建一个多地图,并要求番石榴为您翻转为TreeMultimap,您可以猜到,这是一个TreeMap,每个关键点可以保存多个值。

Multimaps.invertFrom(Multimaps.forMap(myMap), new TreeMultimap<V, K>()); 

Multimap documentation is provided.

+0

唉,我的价值观可能并不是独一无二的,但我会为未来记住这一点。 – 2012-02-06 23:00:48

+0

更新了有关如何使用非唯一值执行此操作的信息。 – 2012-02-07 00:31:46

+0

正是我需要的! – 2012-02-07 11:02:00

2

因为您无法手动重新排序TreeMap的条目。 TreeMap条目是总是按键排序。

我打算抛出Map that could be iterated in the order of values作为“如何做到这一点”的另一个答案,但是......具体来说,一个解决方案不会返回一个映射(通过抛出异常)来查询键值在你的原始地图。

+0

请注意,如果您不屑于阅读OP中引用的问题,您会注意到TreeMaps并非总是按键排序。 Treemaps可以接受一个比较器,它可以在几乎任何东西(包括值)上进行排序。 – gnomed 2012-02-06 22:39:02

+1

我认为将值放入数组中然后对其进行排序可能更容易。 – 2012-02-06 23:05:56

+0

@gnomed:TreeMap总是按键排序,虽然它可能是根据一些古怪的比较器进行排序(这可能很有可能从别处查找值)。事实上,我确实在阅读OP中引用的问题,尽管它提出了一种技术,当你尝试'map.containsKey(keyNotInOriginalMap)'时,坦率地说很容易出现怪异的错误,并且突然间你会遇到非常混乱的异常,并且不知道你为什么得到它们。 – 2012-02-07 00:03:17

1

我有这个这是工作的罚款非常小的代码:

public class SortMapByValues { 
    public static void main(String[] args) { 

     Map<Integer, String> myMap = new LinkedHashMap<Integer, String>(); 

     myMap.put(100, "hundread"); 
     myMap.put(500, "fivehundread"); 
     myMap.put(250, "twofifty"); 
     myMap.put(300, "threehundread"); 
     myMap.put(350, "threefifty"); 
     myMap.put(400, "fourhundread"); 

     myMap = sortMapByValues(myMap); 

     for (Map.Entry<Integer, String> entry : myMap.entrySet()) { 
      System.out.println(entry.getKey() + " " + entry.getValue()); 
     } 

    } 

    public static Map<Integer, String> sortMapByValues(
      Map<Integer, String> firstMap) { 
     Map<String, Integer> SecondyMap = new TreeMap<String, Integer>(); 

     for (Map.Entry<Integer, String> entry : firstMap.entrySet()) { 
      SecondyMap.put(entry.getValue(), entry.getKey()); 
     } 
     firstMap.clear(); 
     for (Map.Entry<String, Integer> entry : SecondyMap.entrySet()) { 
      firstMap.put(entry.getValue(), entry.getKey()); 
     } 
     return firstMap; 
    } 

} 

输出:

500 fivehundread 
400 fourhundread 
100 hundread 
350 threefifty 
300 threehundread 
250 twofifty 
1

我写了下面的一行代码中使用Java 8 Stream API根据值对任何给定的地图进行排序:

List<Map.Entry<String, String>> sortedEntries = map.entrySet().stream() 
    .sorted((o1, o2) -> o1.getValue().compareTo(o2.getValue())).collect(Collectors.toList());