programing

Lambda 식 및 일반 메서드

nasanasas 2020. 8. 15. 09:24
반응형

Lambda 식 및 일반 메서드


일반적인 인터페이스가 있다고 가정합니다.

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

이 오류 메시지에서 컴파일러가 유형 인수를 유추 할 수없는 것 같습니다. 그럴까요? 그렇다면 왜 이런 일이 발생합니까?

인터넷을 통해 다양한 방법으로 검색했습니다. 그런 다음 방법을 보여주는 이 JavaCodeGeeks 기사를 찾았 으므로 시도했습니다.

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);

당신은 사용할 수 없습니다 람다 식을 A에 대한 기능적인 인터페이스 의 방법 경우, 기능적인 인터페이스는형식 매개 변수를 . JLS8의 섹션 §15.27.3을 참조하십시오 .

A lambda expression is compatible [..] with a target type T if T is a functional interface type (§9.8) and the expression is congruent with the function type of [..] T. [..] A lambda expression is congruent with a function type if all of the following are true:

  • The function type has no type parameters.
  • [..]

Using method reference, i found other way to pass the argument:

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

Just point compiler the proper version of generic Comparator with (Comparator<String>)

So the answer will be

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


You mean something like this?:

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

Of what type is this lambda? You couldn't express that in Java and therefore cannot compose this expression in a function application and expressions have to be composable.

For this need to be work you would need support for Rank2 Types in Java.

Methods are allowed to be generic but therefore you couldn't use them as expressions. They can, however be reduced to lambda expression by specializing all necessary generic types before you can pass them: ClassName::<TypeName>methodName

참고URL : https://stackoverflow.com/questions/22588518/lambda-expression-and-generic-method

반응형