5

I have a comparator class in Java to compare Map entries:

public class ScoreComp implements Comparator<Object> {

    public int compare(Object o1, Object o2) {

        Entry<Integer, Double> m1 = null;
        Entry<Integer, Double> m2 = null;

        try {
            m1 = (Map.Entry<Integer, Double>)o1;
            m2 = (Map.Entry<Integer, Double>)o2;
        } catch (ClassCastException ex){
            ex.printStackTrace();
        }

        Double x = m1.getValue();
        Double y = m2.getValue();
        if (x < y)
            return -1;
        else if (x == y)
            return 0;
        else
            return 1;        
     }

}

when I compile this program I get the following:

warning: [unchecked] unchecked cast
found   : java.lang.Object
required: java.util.Map.Entry<java.lang.Integer,java.lang.Double>
            m1 = (Map.Entry<Integer, Double>)o1;

I need to sort map entries on the basis of the Double Values.

If I create the following comparator then I get an error in the call to sort function of Arrays (I am getting an entry set from the map and then using the set as an array).

public class ScoreComp implements Comparator<Map.Entry<Integer, Double>>

how to implement this scenario.

Rohit Banga
  • 18,458
  • 31
  • 113
  • 191

3 Answers3

4

Assuming that you're using this comparator to sort a TreeMap, then this isn't going to work. TreeMap comparators are for comparing only the map keys, not the key->value entries. If your comparator needs access to the values, then it will have to look them up in the map itself, e.g.

final Map<Integer, Double> map = ....

public class ScoreComp implements Comparator<Integer>  {
   public int compare(Integer key1, Integer key2) {
    Double x = map.getValue();
    Double y = map.getValue();
    if (x < y)
        return -1;
    else if (x == y)
        return 0;
    else
        return 1; 
   }
}

edit: From your comments, I think your best option is to create a class that encapsulates the ID and the value, put those values into a List, and sort that.

public class Item implements Comparable<Item> {
   int id;
   double value;

   public int compareTo(Item other) {
      return this.value - other.value;
   }
}

and then

List<Item> list = new ArrayList<Item>();
// ... add items here
Collections.sort(list);

Since Item is itself Comparable, you don't need an external Comparator (unless you want one).

skaffman
  • 398,947
  • 96
  • 818
  • 769
  • what if i need to sort on the basis of values and the values are not unique so that the keys have to be integer and i want to keep the key and the value together, to make my code look easy to understand. – Rohit Banga Feb 01 '10 at 13:00
  • Are you actually using the Integer values for anything? Who not just put the Doubles into a List, and sort that? – skaffman Feb 01 '10 at 13:02
  • after i sort the double values i need to be able to identify which double value belongs to which id. http://stackoverflow.com/questions/2145853/java-treemap-get-values-in-sorted-order – Rohit Banga Feb 01 '10 at 13:03
  • only thing is i could not find a built in pair data structure. – Rohit Banga Feb 02 '10 at 09:42
  • 1
    http://stackoverflow.com/questions/156275/what-is-the-equivalent-of-the-c-pairl-r-in-java – Rohit Banga Feb 02 '10 at 09:44
2

What's about rewriting as

public class ScoreComp implements Comparator<Map.Entry<Integer, Double>> {

    public int compare(Map.Entry<Integer, Double> o1, Map.Entry<Integer, Double> o2) {
        if ( o1.getValue()  < o2.getValue()  ) return -1;
        else if ( o1.getValue() == o2.getValue()  ) return 0;
        return 1;
    }
}
stacker
  • 68,052
  • 28
  • 140
  • 210
  • then i get an error in the call to sort. ` Set> mSet = Score.entrySet(); Object[] arr = mSet.toArray(); Arrays.sort(arr, new ScoreComp());` – Rohit Banga Feb 01 '10 at 12:54
  • No, this won't work, because the `TreeMap` routines will not pass in the `Map.Entry` values, no matter how hard you try to make it compile – skaffman Feb 01 '10 at 12:57
  • well the code in my question was compiling with a version 6.5 of netbeans on windows . but it does not compile on netbeans 6.8 on linux. (java is 1.6 on both - strange) – Rohit Banga Feb 01 '10 at 13:02
2

stacker has described how to fix the code you've shown. Here's how to fix the code in your comment: First of all, don't use arrays, because arrays don't work with generics (you cannot have an array of a generic type). Instead, you can use a List and the Collections.sort() method:

    List<Map.Entry<Integer, Double>> mList = 
        new ArrayList<Map.Entry<Integer, Double>>(Score.entrySet()); 
    Collections.sort(mList, new ScoreComp());
Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • how i wish i could accept two answers as correct. your answer is good but for my work i would be using skaffman's approach. – Rohit Banga Feb 02 '10 at 08:15