Я рассматривал разницу между Collections.sort и list.sort, особенно в отношении использования статических методов Comparator, и требуются ли типы параметров в выражениях лямбда. Прежде чем мы начнем, я знаю, что могу использовать ссылки на методы, например. Song::getTitle, чтобы преодолеть мои проблемы, но мой запрос здесь - это не столько что-то, что я хочу исправить, а то, на что я хочу получить ответ, то есть почему компилятор Java обрабатывает его таким образом.
Это мои находки. Предположим, что у нас есть ArrayList типа Song, с добавленными песнями есть 3 стандартных метода get:
    ArrayList<Song> playlist1 = new ArrayList<Song>();
    //add some new Song objects
    playlist.addSong( new Song("Only Girl (In The World)", 235, "Rhianna") );
    playlist.addSong( new Song("Thinking of Me", 206, "Olly Murs") );
    playlist.addSong( new Song("Raise Your Glass", 202,"P!nk") );
Вот вызов для обоих типов методов сортировки, которые работают, без проблем:
Collections.sort(playlist1, 
            Comparator.comparing(p1 -> p1.getTitle()));
playlist1.sort(
            Comparator.comparing(p1 -> p1.getTitle()));
Как только я начну цепочку thenComparing, произойдет следующее:
Collections.sort(playlist1,
            Comparator.comparing(p1 -> p1.getTitle())
            .thenComparing(p1 -> p1.getDuration())
            .thenComparing(p1 -> p1.getArtist())
            );
playlist1.sort(
        Comparator.comparing(p1 -> p1.getTitle())
        .thenComparing(p1 -> p1.getDuration())
        .thenComparing(p1 -> p1.getArtist())
        );
то есть. синтаксические ошибки, поскольку он больше не знает тип p1. Поэтому, чтобы исправить это, я добавляю тип Song к первому параметру (сравнения):
Collections.sort(playlist1,
            Comparator.comparing((Song p1) -> p1.getTitle())
            .thenComparing(p1 -> p1.getDuration())
            .thenComparing(p1 -> p1.getArtist())
            );
playlist1.sort(
        Comparator.comparing((Song p1) -> p1.getTitle())
        .thenComparing(p1 -> p1.getDuration())
        .thenComparing(p1 -> p1.getArtist())
        );
Теперь вот часть CONFUSING. Для p laylist1.sort, то есть List, это решает все ошибки компиляции для обоих следующих вызовов thenComparing. Однако для Collections.sort он решает его для первого, но не для последнего. Я тестировал добавленные несколько дополнительных вызовов на thenComparing, и он всегда показывает ошибку для последнего, если я не поставил (Song p1) для параметра.
Теперь я продолжал тестировать это, создав TreeSet и используя Objects.compare:
int x = Objects.compare(t1, t2, 
                Comparator.comparing((Song p1) -> p1.getTitle())
                .thenComparing(p1 -> p1.getDuration())
                .thenComparing(p1 -> p1.getArtist())
                );
    Set<Song> set = new TreeSet<Song>(
            Comparator.comparing((Song p1) -> p1.getTitle())
            .thenComparing(p1 -> p1.getDuration())
            .thenComparing(p1 -> p1.getArtist())
            );
То же самое происходит, как и в TreeSet, ошибок компиляции нет, но для Objects.compare последний вызов thenComparing показывает ошибку.
Может кто-нибудь объяснить, почему это происходит, а также почему нет необходимости использовать (Song p1) вообще при простом вызове метода сравнения (без дальнейших вызовов thenComparing).
Еще один запрос по той же теме, когда я делаю это с TreeSet:
Set<Song> set = new TreeSet<Song>(
            Comparator.comparing(p1 -> p1.getTitle())
            .thenComparing(p1 -> p1.getDuration())
            .thenComparing(p1 -> p1.getArtist())
            );
то есть. удалите тип Song из первого параметра лямбда для вызова метода сравнения, он отображает синтаксические ошибки при вызове сравнения и первый вызов thenComparing, но не до последнего вызова thenComparing - почти что противоположно тому, что происходило выше! Принимая во внимание, что для всех остальных 3 примеров, т.е. С Objects.compare, list.sort и Collections.sort, когда я удаляю этот первый тип параметра Song, он показывает синтаксические ошибки для всех вызовов.
Большое спасибо заранее.
Отредактировано, чтобы включить скриншот ошибок, которые я получал в Eclipse Kepler SR2, которые с тех пор я нашел, являются специфичными для Eclipse, потому что при компиляции JCK8 java-компилятора в командной строке он компилирует ОК.
 