archcutbank
archcutbank

Reputation: 479

Confused how to type comparator in another class

I am trying to sort the values of two LinkedHashMap. I can compile it and run the code just fine, but it tells me to use -Xlint option during compiling because it is unsafe code. It has something to do with type casting stuff, but I am royally confused on how to do it. I got this class which I put inbedded in my class:

static class MyComparator implements Comparator {

        public int compare(Object obj1, Object obj2){
            int result=0;
            Map.Entry e1 = (Map.Entry)obj1 ;
            Map.Entry e2 = (Map.Entry)obj2 ;//Sort based on values.

            Integer value1 = (Integer)e1.getValue();
            Integer value2 = (Integer)e2.getValue();

            if(value1.compareTo(value2)==0){

                String word1=(String)e1.getKey();
                String word2=(String)e2.getKey();

                //Sort String in an alphabetical order
                result=word1.compareToIgnoreCase(word2);

            } else {
                //Sort values in a descending order
                result=value2.compareTo( value1 );
            }

            return result;
        }

    }

I tried to call it in one of my functions with:

ArrayList myArrayList=new ArrayList(this.map_freq_by_date.entrySet());
Collections.sort(myArrayList, new MyComparator());
Iterator itr=myArrayList.iterator();

Note: this.map_freq_by_date is defined as follows:

Map<String,Integer> map_freq_by_date = new LinkedHashMap<String,Integer>();

The error I get with -Xlint option:

unchecked call to ArrayList(java.util.Collection<? extends E>) as a member of the raw type java.util.ArrayList
ArrayList myArrayList=new ArrayList(this.map_freq_by_date.entrySet());


unchecked conversion
found LogGrep.MyComparator
required: java.util.Comparator(? super T>
    Collections.sort(myArrayList, new MyComparator());

unchecked method invocation: <T>sort(java.util.List<T>,java.util.Comparator<? super T> in java.util.Collections is applied to (java.util.ArrayList,LogGrep.MyComparator)
    Collections.sort(myArrayList, new MyComparator());

Help with how to fix these would be appreciated. I looked online and tried all kinds of things shown, but I can't seem to get it right.

Note: if I put ArrayList<Object> myArrayList = new ArrayList<Object>... the error changes to:

unchecked method invocation <T>sort(java.util.List<T>,java.util.Comparator<> super T?) in java.util.Collections is applied ot (java.util.ArraList<java.lang.Object>,LogGrep.MyComparator)
        Collections.sort(myArrayList, new MyComparator());

Upvotes: 3

Views: 4837

Answers (3)

Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 298838

Comparator is a Generic Interface. Do it like this:

static class MyComparator implements Comparator<Map.Entry<String, Integer>> {
    public int compare(Map.Entry<String, Integer> obj1, Map.Entry<String, Integer> obj2){
        ...
    }
}

and define your list as

List<Map.Entry<String, Integer>> myArrayList = new ArrayList<Map.Entry<String, Integer>>()

And the compiler will be happy again.

Read the Generics Tutorial for more info. Or Angelika Langer's Generics FAQ.

Btw, unless your Comparator needs runtime parameters or has mutable state, you should define it as a Constant instead of creating a New instance for every call

Upvotes: 4

Bhesh Gurung
Bhesh Gurung

Reputation: 51030

You can do it in a type safe way as follows:

Map<String, Integer> map = new LinkedHashMap<String, Integer>();
map.put("four", 4);
map.put("one", 1);
map.put("five", 5);
map.put("three", 3);
map.put("two", 2);

System.out.println(map);

List<Map.Entry<String, Integer>> entryList = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());        
Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() {
    @Override
    public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
        return e1.getValue().compareTo(e2.getValue());
    }            
});        
map.clear();        
for(Map.Entry<String, Integer> e : entryList) {
    map.put(e.getKey(), e.getValue());
}

System.out.println(map);

Output:

{four=4, one=1, five=5, three=3, two=2}
{one=1, two=2, three=3, four=4, five=5}

Upvotes: 0

Michał Šrajer
Michał Šrajer

Reputation: 31182

You should use Comparator<T> interface not a raw Comparator.

Read this article.

Upvotes: 0

Related Questions