0

I'm trying to sort a map based on different possible values in the Student object. This doesn't seem to be working for me and I can't seem to figure out why. Any help would be very appreciated. Thanks!

protected static Map<Integer, Student> sort(Map<Integer, Student> unsorterMap, String field)
{
    Comparator<Integer> valueComparator =  
            new Comparator<Integer>() 
            {
                public int compare(Integer k1, Integer k2) 
                {
                    int compare;
                    if(field.equalsIgnoreCase("name"))
                    {
                        compare = unsorterMap.get(k1).getName().compareTo(unsorterMap.get(k2).getName());
                    }
                    else
                    {
                        compare = Integer.compare(unsorterMap.get(k1).getIndex(), unsorterMap.get(k2).getIndex());
                    }


                    if (compare == 0)
                        return 1;
                    else
                        return compare;
                }
            };

    Map<Integer, Student> sortedMap = new TreeMap <Integer, Student>(valueComparator);
    sortedMap.putAll(unsorterMap);
    return sortedMap;
}
urbill
  • 1
  • 1
    If you want to compare `Student`s, your `Comparator` implementation should use `Student` as a type parameter and not `Integer`... (`Integer` already implements `Comparable`) – Ryan J Apr 08 '15 at 02:30
  • Also, see [this question](http://stackoverflow.com/questions/2864840/treemap-sort-by-value). – Ryan J Apr 08 '15 at 02:38
  • Thanks for the quick response. I'm not really understanding why I would use student instead of the key. Trying to try out what you said I've run into an issue. The constructor TreeMap(Comparator) is undefined Map sortedMap = new TreeMap (valueComparator); – urbill Apr 08 '15 at 03:31
  • Reason I posted that is usually, to sort a set of values, your comparator must be able to compare the values you're attempting to sort. As circular as that sounds, a `Comparator` should provide the implementation required to compare one `Student` to another. That being said, the `TreeMap` that you're using takes a comparator that compares keys, in order to sort the map. You're not sorting on the values, as that inherently goes against the definition of the TreeMap, hence why I pointed you to that referenced question (which combines both aspects of what you're after). – Ryan J Apr 08 '15 at 04:03

1 Answers1

0

Your comparator violates the Comparator contract. From javadoc:

The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y

But in your code, you have

if (compare == 0)
    return 1;
else
    return compare;

If two students have the same value for the field you use to do the comparison, both compare(x,y) and compare(y,x) will return 1.

Misha
  • 27,433
  • 6
  • 62
  • 78
  • Thanks, it's not sorting wrong, it's not sorting at all I get the same map out as in.I've tried it with just returning compare, and it still doesn't change any thing. – urbill Apr 08 '15 at 03:32
  • @urbill do you have a sample map that doesn't sort correctly? – Misha Apr 08 '15 at 05:04
  • [here is the map, just substitute student for author. The key is = to the index in the author object.](http://imgur.com/zKoeNI6) – urbill Apr 08 '15 at 14:01