1

why if I put an anonymous class with Comparator in the sort method of List the compiler show me an error?

My code:

public class Example2 {

public static void main(String[] args) {
   List<String> l = Arrays.asList("a","b","c","d");
   l.sort(Comparator<String> c= new Comparator<>() {   //compiler error
        public int compare(String a, String b) {
            return b.compareTo(a);
        }
   });

}

The sort method accepts a Comparator. If I write this code, it compiles:

public class Example2 {

public static void main(String[] args) {
   List<String> l = Arrays.asList("a","b","c","d");
   l.sort(new Comparator<String>() {                  //it's ok
        public int compare(String a, String b) {
            return b.compareTo(a);
        }
   });

}

Or this code:

public class Example2 {

public static void main(String[] args) {
   List<String> l = Arrays.asList("a","b","c","d");
   Comparator <String> c = new Comparator<String>() {     
        public int compare(String a, String b) {
            return b.compareTo(a);
        }
   };
   l.sort(c);                               //it's ok

}

Why does it happen?

Thanks a lot!

Sam
  • 536
  • 5
  • 23

3 Answers3

2

In the second example you are not giving the comparator to the method, you are assigning it to the 'c' reference. In the third example you are assigning it to c reference but then giving it to the sort method.

Hope this helps :)

  • Thanks a lot for your answer, but in my opinion, in all examples I assigned a Comparator to sort method, that the sort method accepts. – Sam Nov 10 '18 at 17:58
  • 2
    In `l.sort(Comparator c= new Comparator<>()` you are giving the sort method the return of the expression `Comparator c= new Comparator<>()` which is not a Comparator. – Andrei Dumitrescu-Tudor Nov 10 '18 at 18:01
2

The first one fails as it is an assignment. The sort method expects an object of the Comparator class. So when you say sort(new Comparator), you are creating a new Comparator and immediately passing it to the sort method. When you have Comparator c = new Comparator () and then you have sort(c), you create an new Comparator, store it in variable c, and pass it to the sort method.

The first segment of code tries to both assign a new Comparator to variable c and pass it to method sort, the syntax of java does not allow this. It is analagous to having a method that takes one integer as argument and writing foo(int bar = 7). It doesnt quite make sense.

Jacob
  • 425
  • 3
  • 13
  • It wouldn't matter if it were an assignment; it's not, though, it is a variable declaration, which is a statement, not an expression, and thus cannot be used inside an expression. – Andy Turner Nov 10 '18 at 20:55
2

The problem here is not that you are passing an anonymous class.

l.sort(Comparator<String> c= new Comparator<>() { ... });

This is attempting to declare a variable, c. Variable declarations are statements, and so they cannot be used inside expressions. (You also can't use the diamond operator when declaring an anonymous class).

If you want to declare a variable to hold that comparator, and assign it inside the sort invocation, you can, like so:

Comparator<String> c;
l.sort(c = new Comparator<String>() { ... });

but I suspect that isn't what you intended.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243