I read the Java 8 tutorial on Lambda Expressions and do not quite understand the Method Reference example for "Reference to an instance method of an arbitrary object of a particular type"
In the same tutorial there is an example "Reference to an Instance Method of a Particular Object" which look likes.
public int compareByName(Person a, Person b) {
        return a.getName().compareTo(b.getName());
}
Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);
I can see this working because the method compareByName has the same signature as Comparator.compare, lambda (a, b) -> myComparisonProvider.compareByName(a, b) takes two arguments and calls a method with the same two arguments.
Now the "Reference to an instance method of an arbitrary object of a particular type" example uses String::compareToIgnoreCase
String[] stringArray = { "Barbara", "James", "Mary", "John",
    "Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
The signature for that method is int compareTo(String anotherString) and is different than Comparator.compare. The tutorial is not very clear but seem to imply you end up with a lambda such as (a, b) -> a.compareToIgnoreCase(b) I dont understand how the compiler decides what is acceptable for the second param of Arrays.sort  I thought maybe it is smart enough to understand how to call that method, so I created an example.
public class LambdaTest {
    public static void main(String... args) {
        String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" };
        Arrays.sort(stringArray, String::compareToIgnoreCase);      // This works
        // using Static methods
        Arrays.sort(stringArray, FakeString::compare);              // This compiles
        Arrays.sort(stringArray, FakeString::compareToIgnoreCase);  // This does not
        // using Instance methods
        LambdaTest lt = new LambdaTest();
        FakeString2 fs2 = lt.new FakeString2();
        Arrays.sort(stringArray, fs2::compare);                 // This compiles
        Arrays.sort(stringArray, fs2::compareToIgnoreCase);     // This does not
        for(String name : stringArray){
            System.out.println(name);
        }
    }
    static class FakeString {
         public static int compareToIgnoreCase(String a) {
             return 0;
         }
        public static int compare(String a, String b) {
            return String.CASE_INSENSITIVE_ORDER.compare(a, b);
        }
    }
    class FakeString2 implements Comparator<String> {
         public int compareToIgnoreCase(String a) {
             return 0;
         }
        @Override
        public int compare(String a, String b) {
            return String.CASE_INSENSITIVE_ORDER.compare(a, b);
        }
   }
}
Can some one explain why the above two Arrays.sort don't compile even though they are using methods that are the same as String.compareToIgnoreCase method
 
     
     
    