2015-08-13 91 views
0

我想不通爲什麼我的自定義UpdateableTreeMap類不工作。它應該按照它的值對TreeMap進行排序。TreeMap按價值排序不工作?

全部代碼在這裏:

import org.bukkit.entity.Player; 

import java.util.*; 

public class UpdateableTreeMap { 

    private final HashMap<Player, PlayerData> hashMap; 
    private final TreeMap<Player, PlayerData> treeMap; 

    public UpdateableTreeMap() { 
     hashMap = new HashMap<>(); 
     treeMap = new TreeMap<>(new ValueComparator(hashMap)); 
    } 

    public Map<Player, PlayerData> internalMap() { 
     return hashMap; 
    } 

    public Set<Player> keySet() { 
     return hashMap.keySet(); 
    } 

    public boolean containsKey(Object key) { 
     return hashMap.containsKey(key); 
    } 

    public PlayerData get(Object key) { 
     return hashMap.get(key); 
    } 

    public PlayerData remove(Object key) { 
     treeMap.remove(key); 
     return hashMap.remove(key); 
    } 

    public boolean isEmpty() { 
     return hashMap.isEmpty(); 
    } 

    public int size() { 
     return hashMap.size(); 
    } 

    public Map.Entry<Player, PlayerData> firstEntry() { 
     return treeMap.firstEntry(); 
    } 

    public Set<Map.Entry<Player, PlayerData>> entrySet() { 
     return hashMap.entrySet(); 
    } 

    public Set<Map.Entry<Player, PlayerData>> sortedEntrySet() { 
     return treeMap.entrySet(); 
    } 

    public Collection<PlayerData> values() { 
     return hashMap.values(); 
    } 

    public Collection<PlayerData> sortedValues() { 
     return treeMap.values(); 
    } 

    public PlayerData put(Player key, PlayerData value) { 
     hashMap.put(key, value); 
     return treeMap.put(key, value); 
    } 

    public void update(Player key) { 
     PlayerData value = treeMap.remove(key); 

     if (value != null) { 
      treeMap.put(key, value); 
     } 
    } 

    public static class ValueComparator implements Comparator<Player> { 

     private final Map<Player, PlayerData> map; 

     public ValueComparator(Map<Player, PlayerData> map) { 
      this.map = map; 
     } 

     public int compare(Player o1, Player o2) { 
      if (o1 == o2) 
       return 0; 

      PlayerData d1 = map.get(o1); 
      PlayerData d2 = map.get(o2); 

      System.out.println(o1.getName() + " " + d1.maxhealth + " - " + d2.maxhealth + " " + o2.getName()); 
      System.out.println("Result: " + (o1 == o2 ? 0 : (d1.maxhealth < d2.maxhealth ? 1 : -1))); 

      if (d1.maxhealth < d2.maxhealth) 
       return 1; 
      return -1; 
     } 

    } 

} 

當我打電話update(Player),我可以清楚地看到感謝System.out.println()線是compare(Player, Player)將返回-1。但是,當我使用sortedValues()方法遍歷TreeMap時,順序不正確。

+0

你想要什麼命令?您的代碼首先提供「最健康」。如果它不是您想要的,請更改比較器中的符號。 –

+0

是的,這就是我要找的訂單。但是,它並不一致。 –

+0

嘗試按值對地圖進行排序在大多數情況下從一開始就註定要失敗。比較者破解你正在做的只是爲了解決問題。 http://stackoverflow.com/a/2581754/869736是解決這個問題的唯一可靠方法。 –

回答

2

根據Treemap API,TreeMap.values()返回值在按鍵的順序中,不是值。

公共類別值()

返回包含在此圖中的值的集合圖。

集合的迭代器按相應鍵的升序返回值。該集合的分割器是後期綁定的,失敗很快,並且還報告Spliterator。訂購的訂單號爲的升序爲相應的鑰匙

集合由地圖支持,因此對地圖的更改反映在集合中,反之亦然。如果在對集合進行迭代的過程中修改了映射(除了通過迭代器自己的刪除操作),迭代的結果是未定義的。該集合支持元素刪除,通過Iterator.remove,Collection.remove,removeAll,retainAll和clear操作從映射中刪除相應的映射。它不支持add或addAll操作。

指定者:接口Map 值指定者: 值接口SortedMap的 覆蓋:類 值AbstractMap 返回: 在此地圖包含

提示值的集合視圖:您可以額外的成本對TreeMap.values()進行排序。

+0

我的比較器通過它的值對Map進行排序,通過使用該鍵首先檢索值。 –

+1

你的比較器有兩種破壞方式,其中包括:如果兩個'PlayerData'具有相同的'maxhealth',那麼它們的比較都大於彼此;同樣,比較可以隨時間變化,而'TreeMap'不能反映。 –

1

我放棄了,最後切換到谷歌的TreeMultiMap