3

So I want to use TreeMap with a customized comparator My key is a String: id, my value is an int: count; I NEED TO COMPARE THE COUNT, AS THE VALUE(INTEGER) IN THE TREEMAP So I have:

In one class:

import java.util.*;

public TreeMap<String, Integer> tm = new TreeMap<String, Integer>(new SortIdCount<Integer>());

In another class:

import java.util.Comparator;

public class SortIdCount implements Comparator<Integer>{

    public int compare(Integer count1, Integer count2) {
        return count1.compareTo(count2);
    }

}

It shows error in eclipse:

The type SortIdCount is not generic; it cannot be parameterized with arguments <Integer>
wnl2367
  • 69
  • 1
  • 6

5 Answers5

1

The type SortIdCount is not generic; it cannot be parameterized with arguments < Integer >

Reason : Class SortIdCount is not genric type so you can not pass parameterized argument. Error At Line : (new SortIdCount<Integer>()

Note : A TreeMap is always sorted based on its keys, however if you want to sort it based on its values then you can build a logic to do this using comparator. Below is a complete code of sorting a TreeMap by values.

To Sort on Values You can refer below code snippet.

import java.util.*;

public class TreeMapDemo {
  //Method for sorting the TreeMap based on values
  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(k1).compareTo(map.get(k2));
        if (compare == 0) 
          return 1;
        else 
          return compare;
      }
    };

    Map<K, V> sortedByValues = 
      new TreeMap<>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
  }
  public static void main(String args[]) {

    TreeMap<String, Integer> treemap = new TreeMap<>();

    // Put elements to the map
    treemap.put("Key1", 5);
    treemap.put("Key2", 4);
    treemap.put("Key3", 3);
    treemap.put("Key4", 2);
    treemap.put("Key5", 1);

    // Calling the method sortByvalues
    Map sortedMap = sortByValues(treemap);

    // Get a set of the entries on the sorted map
    Set set = sortedMap.entrySet();

    // Get an iterator
    Iterator i = set.iterator();

    // Display elements
    while(i.hasNext()) {
      Map.Entry me = (Map.Entry)i.next();
      System.out.print(me.getKey() + ": ");
      System.out.println(me.getValue());
    }
  }
}

For more details refer this answer

Snehal Patel
  • 1,282
  • 2
  • 11
  • 25
1

As others might already have mentioned, that the Comparator used in the TreeMap constructor is used to sort the map by key.

public TreeMap(Comparator comparator)

... ordered according to the given comparator. All keys inserted into the map must be mutually comparable by the given comparator: comparator.compare(k1, k2) must not throw a ClassCastException for any keys k1 and k2 in the map...

But if you want to sort a map by the value, still we have a solution using LinkedHashMap as:

    Map<String, Integer> treeMap = new TreeMap<>();
    treeMap.put("hi", 1);
    treeMap.put("there", 3);
    treeMap.put("hey", 2);
    treeMap = treeMap.entrySet().stream().sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue()))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldV, newV) -> oldV, LinkedHashMap::new));
    System.out.println(treeMap);

Output:

{there=3, hey=2, hi=1}
Hearen
  • 7,420
  • 4
  • 53
  • 63
0

You can't have a TreeMap which sort by value. There are so many ways to sort a map by value but I believe TreeMap is not for that. If you look on the TreeMap constructor: TreeMap(Comparator<? super K> comparator) which takes comparator as an argument which's generic type clearly should be the super of Key of the Map. So it impossible to send a Comparator<Integer> when the key is String.

Please follow the answer for sorting Map by value.

Amit Bera
  • 7,075
  • 1
  • 19
  • 42
0

The comparator used for a TreeMap has to compare the keys, not the values.

So the comparison would have to take the passed key and look up the value in the map. And there you have a classical hen (map) and egg (comparator) problem. You need the comparator to create the map, but since the comparator has to look into the map, you need the map for the comparator. You could solve this by having comparator.setMap(map) after creation of the map.

But the most critical problem is, that your map will not work. As long as the entry is not written to the map, you don't have the value, so the comparator won't work. Only idea I have for that is using two maps. Both String, Integer. The first one is simply used for the lookup in the comparator. So you always have to put into the first and then into the second.

And then you still have problems, because you might easily violate the SortedMap contract. A key must not change (regarding the sorting) after it is inserted into the map. But as soon as you put another value, you have a different sorting of the key.

So I'd really rethink your requirements and whether a TreeMap is the best solution to what you need.

jokster
  • 577
  • 5
  • 14
-1
public class SortIdCount implements Comparator<String> {

    public int compare(String count1, String count2) {
        return count1.compareTo(count2);
    }
}
Sanjeev
  • 153
  • 1
  • 10