2016-01-31 74 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)),因爲它在內部與紅黑樹實現。