programing

Comparator.reversed()는 lambda를 사용하여 컴파일하지 않습니다.

copysource 2023. 2. 3. 23:18
반응형

Comparator.reversed()는 lambda를 사용하여 컴파일하지 않습니다.

일부 사용자 객체가 포함된 목록이 있으며 목록을 정렬하려고 하지만 메서드 참조를 통해서만 작동합니다. lambda 식에서는 컴파일러가 오류를 표시합니다.

List<User> userList = Arrays.asList(u1, u2, u3);
userList.sort(Comparator.comparing(u -> u.getName())); // works
userList.sort(Comparator.comparing(User::getName).reversed()); // works
userList.sort(Comparator.comparing(u -> u.getName()).reversed()); // Compiler error

오류:

com\java8\collectionapi\CollectionTest.java:35: error: cannot find symbol
            userList.sort(Comparator.comparing(u -> u.getName()).reversed());
                                                     ^
symbol:   method getName()
location: variable u of type Object
1 error

이것은 컴파일러 타입의 회의 메커니즘의 약점입니다.의 유형을 추론하기 위해u람다에서 람다의 목표값 유형을 설정해야 합니다.이것은 다음과 같이 이루어집니다. userList.sort()형식 인수를 필요로 합니다.Comparator<User>첫 번째 줄에Comparator.comparing()반환할 필요가 있다Comparator<User>이것은, 을 나타내고 있다.Comparator.comparing()필요Function그 일에는User논쟁.그래서 첫 번째 줄의 람다에서는u종류여야 한다User모든 게 잘 풀려요

두 번째 줄과 세 번째 줄에서는 타깃타이핑이 콜의 존재에 의해 중단됩니다.reversed()이유는 잘 모르겠습니다.수신기 타입과 반환 타입 모두reversed()이다Comparator<T>그래서 타깃 타입은 리시버에게 전파되어야 할 것 같은데 그렇지 않다.(말씀 드렸듯이 약점입니다)

두 번째 줄에서 메서드 참조는 이 공백을 메우는 추가 유형 정보를 제공합니다.이 정보는 세 번째 줄에 없기 때문에 컴파일러는 다음과 같이 추론합니다.u되려고Object(최종 수단의 추론 폴백), 실패한다.

물론 메서드 레퍼런스를 사용할 수 있다면 그렇게 하면 효과가 있습니다.예를 들어 추가 매개 변수를 전달하려는 경우 방법 참조를 사용할 수 없으므로 람다 식을 사용해야 합니다.이 경우 람다에 명시적 매개변수 유형을 제공합니다.

userList.sort(Comparator.comparing((User u) -> u.getName()).reversed());

향후 릴리즈에서는 컴파일러가 이 케이스를 커버하도록 확장될 가능성이 있습니다.

2개의 인수를 사용하여 이 제한을 회피할 수 있습니다.Comparator.comparing와 함께Comparator.reverseOrder()두 번째 인수:

users.sort(comparing(User::getName, reverseOrder()));

현상금이 수여된 인정되고 상향 투표된 답변과는 달리, 이것은 람다와는 전혀 관련이 없다.

다음 컴파일은 다음과 같습니다.

Comparator<LocalDate> dateComparator = naturalOrder();
Comparator<LocalDate> reverseComparator = dateComparator.reversed();

단, 다음 항목은 그렇지 않습니다.

Comparator<LocalDate> reverseComparator = naturalOrder().reversed();

이는 컴파일러의 유형 추론 메커니즘이 두 단계를 동시에 수행할 수 있을 만큼 강력하지 않기 때문입니다.reversed()method call needs type 파라미터LocalDate그 때문에,naturalOrder()메서드 콜에는 같은 타입 파라미터가 필요합니다.

메서드를 호출하여 유형 파라미터를 명시적으로 전달하는 방법이 있습니다.단순한 경우에는 추측이 가능하기 때문에 필수는 아니지만 다음과 같이 할 수 있습니다.

Comparator<LocalDate> reverseComparator = Comparator.<LocalDate>naturalOrder().reversed();

질문의 예에서는 다음과 같이 됩니다.

userList.sort(Comparator.comparing<User, String>(u -> u.getName()).reversed());

, 현재 있는에서 알 수 가 타입을 하는 데 이 되는 것은 .User★★★★★★★★★★★★★★★★의 경우comparing 메서드콜은 이으로 지정하거나 할 수도 있습니다.User::getName '라는 글자도 있어요.User.

방식 " " "Collections.reverseOrder(Comparator<T>)가장 우아한 해결책인 것 같습니다. 한 가지 Comparator.reverseOrder()T는 동등한 것을 구현하고 자연스러운 정렬 순서에 의존해야 합니다.

Collections.reverseOrder(Comparator<T>)에는, 타입 「」에 되지 않습니다.T

언급URL : https://stackoverflow.com/questions/25172595/comparator-reversed-does-not-compile-using-lambda

반응형