HElwy
HElwy

Reputation: 81

Sorted map won't allow removal

I searched earlier for a way to sort TreeMaps according to the values, was able to find a function that does that, but now it seems something's wrong with the remove() method, tried various different ways to remove using a key but its not working, and to tell the truth I don't fully understand the sorting function, can someone explain what is the problem?

The Code:

public static void main(String[] args) {
    TreeMap<String,Integer> theTree = new TreeMap<String,Integer>();
    theTree.put("A", 5);
    theTree.put("B", 3);
    theTree.put("F", 1);
    theTree.put("D", 5);
    theTree.put("E", 6);
    theTree.put("C", 7);
    System.out.println(theTree.toString());
    Map<String,Integer> sortedTree = new TreeMap<String,Integer>();
    sortedTree = sortByValues(theTree);
    System.out.println(sortedTree.toString());
    for (Map.Entry<String, Integer> entry : sortedTree.entrySet())
    {
        if(entry.getKey().equals("A"))
            sortedTree.remove(entry.getKey());
    }
    System.out.println(sortedTree.toString());
    theTree = new TreeMap<String,Integer>(sortedTree);
    theTree.remove("B");
    System.out.println(theTree.toString());
}

public static <K, V extends Comparable<V>> Map<K, V> sortByValues(final Map<K, V> map) {
    Comparator<K> valueComparator =  new Comparator<K>() {
        public int compare(K k1, K k2) {
            int compare = map.get(k2).compareTo(map.get(k1));
            if (compare == 0) return 1;
            else return compare;
        }
    };
    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
}

The Output:

{A=5, B=3, C=7, D=5, E=6, F=1}
{C=7, E=6, A=5, D=5, B=3, F=1}
{C=7, E=6, A=5, D=5, B=3, F=1}
{A=5, C=7, D=5, E=6, F=1}

The A is still in the map

Upvotes: 0

Views: 294

Answers (2)

harsh
harsh

Reputation: 7692

You can delete only via Iterator during map traversal:

Map<String,Integer> sortedTree = new TreeMap<String,Integer>();
            System.out.println(sortedTree.toString());
            Iterator<Entry<String,Integer>> itr = sortedTree.entrySet().iterator();
            while(itr.hasNext())
            {
                Entry<String,Integer> entry = itr.next();
                if(entry.getKey().equals("A"))
                    itr.remove();
            }

map.remove would work fine while not under iteration else removal would throw ConcurrentModificationException if iteration is not happening via Iterator. That's the case with many other collections too.

This is what I meant as per TreeMap javadoc:

The iterators returned by the iterator method of the collections returned by all of this class's "collection view methods" are fail-fast: if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a
ConcurrentModificationException.

Upvotes: 1

Sinkingpoint
Sinkingpoint

Reputation: 7624

In your Comparator, you are removing any chance of it returning 0 (if (compare == 0)return 1) Thus when you go to remove, there is never any chance for your inputted value to equal a value in the Set and nothing will be removed. If there is no particular reason why you are removing the chance for them to be deemed equal, just remove that line from your comparator.

Upvotes: 4

Related Questions