특히 정적 메서드 사용과 람다 식에 매개 변수 형식이 필요한지 여부와 관련하여 Collections.sort
및 의 차이점을 살펴 보았습니다 . 시작하기 전에, 예 를 들어 내 문제를 극복하기 위해 메소드 참조를 사용할 수 있다는 것을 알고 있지만 여기에서 내 쿼리는 수정하고 싶은 것이 아니라 대답을 원하는 것입니다. 즉, Java 컴파일러가 이러한 방식으로 처리하는 이유 .list.sort
Comparator
Song::getTitle
이것이 내 발견입니다. 일부 노래가 추가 된 ArrayList
유형 이 있다고 가정 Song
하면 세 가지 표준 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())
);
이제 혼란스러운 부분이 있습니다. 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
모든 통화에 대해 PARAM 유형이 쇼 구문 오류를.
미리 감사드립니다.
Eclipse Kepler SR2에서 수신 한 오류의 스크린 샷을 포함하도록 편집되었습니다. 이제 이클립스에만 해당됩니다. 명령 줄에서 JDK8 자바 컴파일러를 사용하여 컴파일 할 때 정상적으로 컴파일되기 때문입니다.