简体   繁体   中英

TreeMap sorted by value not working?

I can not figure out why my custom UpdateableTreeMap class is not working. It is supposed to sort a TreeMap by its value.

Full code here:

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

    }

}

When I call update(Player) , I can clearly see thanks to the System.out.println() lines that compare(Player, Player) is returning -1. Yet, when I loop through the TreeMap using the sortedValues() method, the order is incorrect.

Per Treemap API, TreeMap.values() returns values IN THE ORDER OF KEYS , not values.

public Collection values()

Returns a Collection view of the values contained in this map.

The collection's iterator returns the values in ascending order of the corresponding keys. The collection's spliterator is late-binding, fail-fast, and additionally reports Spliterator. ORDERED with an encounter order that is ascending order of the corresponding keys .

The collection is backed by the map, so changes to the map are reflected in the collection, and vice-versa. If the map is modified while an iteration over the collection is in progress (except through the iterator's own remove operation), the results of the iteration are undefined. The collection supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Collection.remove, removeAll, retainAll and clear operations. It does not support the add or addAll operations.

Specified by: values in interface Map Specified by: values in interface SortedMap Overrides: values in class AbstractMap Returns: a collection view of the values contained in this map

Hint: You can sort TreeMap.values() at additional cost.

我放弃了,最终切换到Google的TreeMultiMap

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM