-2

I have this:

import java.util.*;
import java.io.*;

class MyComparator<K,V> implements Comparator<Map.Entry<K,List<V>>> {

    public int compare(Map.Entry<K,List<V>> me1, Map.Entry<K,List<V>> me2) {

                List<V> v1 = me1.getValue();
                List<V> v2 = me2.getValue(); 

                if(v1.size() > v2.size())
                    return 1;
                else if(v1.size() < v2.size())
                    return -1;
                else
                     return 0;
    }
}

public class Anagrams1 {
    public static void main(String[] args) {
        int minGroupSize = Integer.parseInt(args[1]);

        // Read words from file and put into a simulated multimap
        Map<String, List<String>> m = new HashMap<String, List<String>>();

        try {
            Scanner s = new Scanner(new File(args[0]));
            while (s.hasNext()) {
                String word = s.next();
                String alpha = alphabetize(word);
                List<String> l = m.get(alpha);
                if (l == null)
                    m.put(alpha, l=new ArrayList<String>());
                l.add(word);
            }
        } catch (IOException e) {
            System.err.println(e);
            System.exit(1);
        }

        // Print all permutation groups above size threshold
        Collection<Map.Entry<String,List<String>>> c = m.entrySet();
        Object[] arr = c.toArray();
        Arrays.sort(arr, new MyComparator());
        for(Object o : arr) {
            if(m.get(o).size() >= minGroupSize)

                System.out.println(o + " : " + m.get(o).size() + ": " + m.get(o)); 

        }
    }

    private static String alphabetize(String s) {
        char[] a = s.toCharArray();
        Arrays.sort(a);
        return new String(a);
    }
}

This is giving me two warnings:

  javacode$ javac -Xlint:unchecked Anagrams1.java

  Anagrams1.java:45: warning: [unchecked] unchecked method invocation: method sort in class Arrays is applied to given types
          Arrays.sort(arr, new MyComparator());

                     ^
    required: T[],Comparator<? super T>

    found: Object[],MyComparator

    where T is a type-variable:

      T extends Object declared in method <T>sort(T[],Comparator<? super T>)

  Anagrams1.java:45: warning: [unchecked] unchecked conversion

          Arrays.sort(arr, new MyComparator());

                           ^
    required: Comparator<? super T>

    found:    MyComparator

    where T is a type-variable:

      T extends Object declared in method <T>sort(T[],Comparator<? super T>)

Help needed. Thanks.

Ankur Agarwal
  • 19,924
  • 32
  • 117
  • 182
  • 1
    Well, since this is the third question (including the deleted one) about generics and (almost) the same code: have you ever read something about generics? How they work and how one can use them? – Tom Jun 28 '15 at 06:29
  • @Tom I read the tutorial and I am reading it again. I felt getting tips from people to supplement with my reading would be a good and quick way to learn. I am currently reading this: http://docs.oracle.com/javase/tutorial/extra/generics/subtype.html – Ankur Agarwal Jun 28 '15 at 06:31

3 Answers3

1

You've defined class MyComparator<K,V>.

You're calling new MyComparator(). With an Object[].

This should give you the exact warning it's giving you - it's expecting to be defined new MyComparator<String, String>() based on your code.

I'd also recommend passing in a properly typed List instead of an Object[] as the first argument, and using Collections.sort instead.

Krease
  • 14,501
  • 8
  • 47
  • 82
1

There are two approaches to this that I'd suggest:

  1. Use Collection#toArray(T[]) to get an array of the elements of type T[]. This is tricky and icky because you'd need T to be Map.Entry<K,List<V>>, and you can't create one of those directly since generics are non-reifiable types.
  2. Copy the elements into an ArrayList (e.g. using new ArrayList<>(m.entrySet())) and then call Collections.sort on that.

The latter would be my preferred approach, since Collections have type safety advantages over plain arrays.

Andy Turner
  • 122,430
  • 10
  • 138
  • 216
  • "and you can't create one of those directly since generics are non-reifiable types." What does that mean ? Can you please explain in simplistic terms ? – Ankur Agarwal Jun 28 '15 at 06:43
  • http://stackoverflow.com/questions/2927391/whats-the-reason-i-cant-create-generic-array-types-in-java – Andy Turner Jun 28 '15 at 06:44
1

This would still give you a warning in the assignment of the Map.Entry[] to Map.Entry<String,List<String>>[], but the Arrays.sort call won't give any warning :

    Map.Entry<String,List<String>>[] arr = c.toArray(new Map.Entry[0]);
    Arrays.sort(arr, new MyComparator<String,String>());

I don't think you can get away with that warning if you want to use an array for the sorting, since you can't create an instance of a generic array, so c.toArray(new Map.Entry<String,List<String>>[0]) won't pass compilation.

Eran
  • 359,724
  • 45
  • 626
  • 694
  • Using `Collections.sort` will eliminate the need to use an array (and that extra warning) – Krease Jun 28 '15 at 06:42
  • I could not compile after the changes: javacode$ java Anagrams1 ./dictionary.txt 8 Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.util.Map$Entry; at Anagrams1.main(Anagrams1.java:44) Trying Collections.sort approach now. – Ankur Agarwal Jun 28 '15 at 07:13
  • Why could not I do the cast, why the error as above ? – Ankur Agarwal Jun 28 '15 at 07:14
  • @abc Try the new code. I tried multiple versions of this code and ended up posing a version I didn't check that didn't work. Sorry about that. – Eran Jun 28 '15 at 07:17
  • @Eran It worked, but gave two warnings code : http://pastebin.com/zE3vM5uk Warnings: http://pastebin.com/9f9FqxRv – Ankur Agarwal Jun 28 '15 at 08:19