programing

람다 식 및 일반이 메서드에만 정의됨

kingscode 2022. 10. 9. 11:31
반응형

람다 식 및 일반이 메서드에만 정의됨

범용 인터페이스가 있다고 가정합니다.

interface MyComparable<T extends Comparable<T>>  {
    public int compare(T obj1, T obj2);
}

그리고 방법sort:

public static <T extends Comparable<T>> 
       void sort(List<T> list, MyComparable<T> comp) {
    // sort the list
}

이 메서드를 호출하여 람다 식을 인수로 전달할 수 있습니다.

List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));

그건 잘 될 거예요.

단, 인터페이스를 일반적이지 않고 메서드를 범용으로 하면 다음과 같이 됩니다.

interface MyComparable {
    public <T extends Comparable<T>> int compare(T obj1, T obj2);
}

public static <T extends Comparable<T>> 
       void sort(List<T> list, MyComparable comp) {
}

그런 다음 다음과 같이 호출합니다.

List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));

컴파일이 안 돼요.람다 식에 다음과 같은 오류가 표시됩니다.

"대상 메서드가 일반"

좋아요, 제가 이걸 컴파일 했을 때javac, 다음의 에러가 표시됩니다.

SO.java:20: error: incompatible types: cannot infer type-variable(s) T#1
        sort(list, (a, b) -> a.compareTo(b));
            ^
    (argument mismatch; invalid functional descriptor for lambda expression
      method <T#2>(T#2,T#2)int in interface MyComparable is generic)
  where T#1,T#2 are type-variables:
    T#1 extends Comparable<T#1> declared in method <T#1>sort(List<T#1>,MyComparable)
    T#2 extends Comparable<T#2> declared in method <T#2>compare(T#2,T#2)
1 error

이 에러 메시지로부터 컴파일러는 type 인수를 추론할 수 없는 것 같습니다.그런가요?만약 그렇다면 왜 이런 일이 일어나는 걸까요?

나는 여러 가지 방법을 시도했고, 인터넷을 통해 검색했다.그리고 이 Java Code Geeks 기사를 발견했는데, 그 기사가 방법을 보여 주었기 때문에 다음과 같이 시도했습니다.

sort(list, <T extends Comparable<T>>(a, b) -> a.compareTo(b));

기사에서 말하는 것과 달리 또 작동하지 않는 거죠일부 초기 빌드에서 작동했을 수 있습니다.

그래서 제가 묻고 싶은 것은 일반적인 방법으로 람다 표현을 만들 수 있는 방법이 있을까요?메서드를 생성하여 메서드 참조를 사용하여 이 작업을 수행할 수 있습니다.

public static <T extends Comparable<T>> int compare(T obj1, T obj2) {
    return obj1.compareTo(obj2);
}

어떤 계급에서는SO, 그리고 다음과 같이 전달합니다.

sort(list, SO::compare);

기능 인터페이스의 메서드에 유형 매개 변수가 있는 경우 기능 인터페이스람다 식을 사용할 수 없습니다.JLS8의 제15.27.3항을 참조해 주세요.

람다 식은 T가 함수 인터페이스 타입(θ9.8)이고, 그 식이 [..] T의 함수 타입일치하면 [..] 람다 식은 다음 조건이 모두 충족되면 함수 타입과 일치한다.

  • 함수 유형에 유형 매개 변수가 없습니다.
  • [..]

메서드 참조를 사용하여 인수를 전달할 다른 방법을 찾았습니다.

List<String> list = Arrays.asList("a", "b", "c");        
sort(list, Comparable::<String>compareTo);

포인트 컴파일러를 사용하여 범용 Comparator의 적절한 버전을(Comparator<String>)

그래서 정답은

sort(list, (Comparator<String>)(a, b) -> a.compareTo(b));

이런 거 말하는 거야?

<T,S>(T t, S s)->...

이 람다는 어떤 종류입니까?자바에서는 표현할 수 없기 때문에 함수 어플리케이션에서는 이 식을 작성할 수 없기 때문에 식을 합성할 수 있어야 합니다.

이 작업을 위해서는 Java의 Rank 2 Type 지원이 필요합니다.

메서드는 일반적일 수 있지만 표현식으로 사용할 수 없습니다.그러나 전달하기 전에 필요한 모든 일반 유형을 전문화하면 람다 표현으로 축소할 수 있습니다.ClassName::<TypeName>methodName

List<String> list = Arrays.asList("a", "b", "c");        
sort(list, Comparable::<String>compareTo);

int compareTo (T o)는 범용 메서드 호출이 아닙니다.일일 ~일도 although although although although 。Comparable<T>는 유형을 가진 인터페이스입니다.compareToT discriptions.T compareTo (T o)아직 일반적인 방법은 아닙니다.인 방법이 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , . .type parameters discriptions.<T> T compareTo (T o).

언급URL : https://stackoverflow.com/questions/22588518/lambda-expression-and-generic-defined-only-in-method

반응형