2016-01-31 45 views
0

我有一个HashMap看起来像:反向HashMap的

HashMap<Player, Integer> playerHashMap = new HashMap<>();

播放器是包含姓名,号码,年龄等

物件,现在我已经整理它,它像loookts这样的:

key , value 
----------------- 
Player1, 1 
Player2, 2 
Player3, 4 
Player4, 6 

但我想实现的价值反转这张地图上,像这样:

key , value 
----------------- 
Player4, 6 
Player3, 4 
Player2, 2 
Player1, 1 

任何想法?

排序方法(由值排序)看起来像这样:

private static HashMap<Player, Integer> sortByValues(HashMap<Player, Integer> map) { 
      List list = new LinkedList(map.entrySet()); 

      Collections.sort(list, new Comparator<Object>() { 
       public int compare(Object o1, Object o2) { 
        return ((Comparable) ((Map.Entry) (o1)).getValue()) 
         .compareTo(((Map.Entry) (o2)).getValue()); 
       } 
      }); 

      HashMap<Player, Integer> sortedHashMap = new LinkedHashMap<Player, Integer>(); 
      for (Iterator<?> it = list.iterator(); it.hasNext();) { 
       Map.Entry<Player, Integer> entry = (Map.Entry<Player, Integer>) it.next(); 
        sortedHashMap.put(entry.getKey(), entry.getValue()); 
      } 
      return sortedHashMap; 
     } 
+4

“*现在我已经对它排序了*”,因为HashMap不能保证任何顺序,所以听起来并不真实。如果你的意思是你可以按照所描述的顺序打印它们,而不是按照不同的顺序打印它? – Pshemo

+0

你是如何“排序”你的HashMap的?代码在哪里? – scrappedcola

+0

我编辑我的文章,并添加如何看起来方法排序HashMap。 – czArek

回答

1

您是如何对此进行排序的? (基本)HashMap不定义元素之间的顺序。 我用这个:

public static <K extends Comparable<K>,V> List<Entry<K,V>> sortByKeys(Map<K,V> map, final Comparator<K> cmp) 
{ 
    List<Entry<K, V>> ret = new ArrayList<>(); 
    for(Entry<K,V> kv : map.entrySet()) 
     ret.add(kv); 


    Collections.sort(ret,((Comparator) new Comparator<Entry<K,?>>() 
    { 
     @Override 
     public int compare(Entry<K, ?> o1, Entry<K, ?> o2) 
     { 
      return cmp.compare(o1.getKey(), o2.getKey()); 
     } 
    })); 

    return ret; 
} 

您可以指定比较订购挂单的返回列表。

=====

编辑: 这是使用哪个在乎为了一个Map实现一个不错的主意。 你可以简单地修改代码以指定顺序,只需修改页眉和这一行:

-private static HashMap<Player, Integer> sortByValues(HashMap<Player, Integer> map) { 
+private static HashMap<Player, Integer> sortByValues(HashMap<Player, Integer> map, final boolean reverse) { 

和块:

-return ((Comparable) ((Map.Entry) (o1)).getValue()) 
+return (reverse?-1:1)*((Comparable) ((Map.Entry) (o1)).getValue()) 
+0

它的作品:)谢谢!我知道这是我的尝试不好,但我是解决我的问题的第一个想法。我有一个数据库,其中包含许多玩家事件,并且我想从事件表中轻松获取玩家和他的目标 – czArek

+1

在比较器的返回值(正值,负值或零)中应用的java元素比较。在场景后面,java调用带有两个元素的比较器需要进行比较,排序算法通过返回值决定要做什么。值的大小不关心它是否定的或零或为零。所以如果你没有改变比较器返回值的符号,你可以得到升序图,如果你这样做(与-1相乘),你会得到相反的顺序。 –

1

事实是HashMap中不garantee迭代的任何特定顺序。所以你很幸运,你的名单完全以任何方式排序。要解决您的问题,您必须将表格行整理为一个实体,以便value链接到相应的player。为此,您可以直接使用Map.Entry,并将它们置于集合中,但您需要一个自定义比较器。在你的例子中,最好使用通常的ArrayList来完成任务,并用Collections.sort()来排序。要颠倒顺序,否定从比较器返回的结果:

class Player {} 

public static void main(String[] args) { 
    HashMap<Player, Integer> all = new HashMap<>(); 
    List<Map.Entry<Player, Integer>> sorted = sortByValues(all); 
    for (Map.Entry<Player, Integer> e : sorted) { 
     System.out.println("Player: " + e.getKey()); 
     System.out.println("Value: " + e.getValue()); 
    } 
} 

private static List<Map.Entry<Player, Integer>> sortByValues(HashMap<Player, Integer> map) { 
    List<Map.Entry<Player, Integer>> list = new ArrayList<>(map.entrySet()); 

    Collections.sort(list, new Comparator<Map.Entry<Player, Integer>>() { 
     public int compare(Map.Entry<Player, Integer> e1, Map.Entry<Player, Integer> e2) { 
      //use minus to reverse the order 
      return -e1.getValue().compareTo(e2.getValue()); 
     } 
    }); 

    return list; 
} 
+0

它也loooks很好;) – czArek

2

可以使用的java.util.TreeMap和传递按照你想要的方式对它们进行排序。

但是我仍然想知道为什么你有玩家作为一个键和整数作为一个价值? 如果您仅将Integer用于排序,那么您可能需要将Key和值交换为更好的使用Maps的标准方式。 另外,如果您不需要使用散列技术访问对象(也就是说,如果您的集合在哈希会提高性能的地方不会太大),请考虑一个简单的List。

+0

关键是玩家,因为我需要访问他所有的信息,并且值是整数,因为它代表了我计算并在之前增加的目标数量。 – czArek

+1

如果排序是唯一必须实现的,则可以通过颠倒compareTo方法中的项目(swap o1和o2)或者在返回之前将表达式添加 - return - ((Comparable)( (Map.Entry)(o1))。getValue()) .compareTo(((Map.Entry)(o2))。getValue());无论哪种方式,我仍会重新考虑设计,要么没有任何目标作为键或作为播放器对象中的属性。但是我会把这个决定留给你,因为你更了解应用程序。尝试上面的调整来反向排序它们。 – Sathiesh

1

我不确定你为什么要返回单独的地图。你已经有了List,你可以简单地按存储条目的值进行排序。
也不要限制自己使用特定类型的地图,如HashMap。你可能没有获得任何东西,但是你很难改变你的实现到其他类型的Map。

所以,你的代码可能是这样的:

private static List<Map.Entry<Player, Integer>> entriesSoltedByValue(
     Map<Player, Integer> map) { 
    List<Map.Entry<Player, Integer>> list = new ArrayList<>(map.entrySet()); 

    list.sort(Comparator.comparing(Map.Entry<Player, Integer>::getValue).reversed()); 

    return list; 
} 

或者使用流:

private static List<Map.Entry<Player, Integer>> entriesSoltedByValue(
     Map<Player, Integer> map) { 
    return map.entrySet() 
      .stream() 
      .sorted(Comparator 
        .comparing(Map.Entry<Player, Integer>::getValue) 
        .reversed()) 
      .collect(Collectors.toList()); 
} 
1

总之你不能设置为一个HashMap。如果您需要与HashMap相同的功能,但订购时应使用TreeMap

Map<String, Integer> orderedMap = new TreeMap(Collections.reverseOrder()); 
orderedMap.putAll(playerHashMap); 

HashMap给你O(1)插入和搜索,而他们为O在TreeMap(的log(n)),因为它在内部与红黑树实现。