2015-02-05 5 views
6

난 항상 유일한 자바 6를 사용했고 지금 내가 여기에이 기사를 읽고 있었다 자바 8의 새로운 기능에 대해 배울 잡기 오전 : http://www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764?pgno=2BiFunction 참조를 함수 인터페이스를 예상하는 메서드에 전달할 수 있습니까?

을 그리고 그것은 말한다 :

자바 API java.util.function 패키지의 몇 가지 일반 기능 인터페이스를 정의합니다.

BiFunction 빌려 = (첫 번째, 두 번째 : 인터페이스 중 하나 BiFunction는, 그 유형의 변수에 우리의 문자열 비교 람다을 절약 할 수 있습니다 매개 변수 유형 T와 U와 반환 형식 R. 당신과 기능을 설명합니다) -> Integer.compare (first.length(), second.length());

하지만 정렬하는 데 도움이되지 않습니다. 거기에 BiFunction 원하는 Arrays.sort 메서드가 없습니다. 이전에 함수형 프로그래밍 언어를 사용했다면이 흥미로운 것을 발견 할 수 있습니다. 그러나 자바 프로그래머를위한 은 꽤 자연 스럽습니다. Comparator와 같은 인터페이스는 주어진 매개 변수와 반환 유형이있는 메소드가 아니라 특정 용도로 사용됩니다. Java 8은이 맛을 유지합니다. 을 람다 식으로 처리하려면 여전히 표현식을 염두에두고 특정 기능을 가진 인터페이스가 필요합니다. 나는이 스레드 볼 때

그러나 : 질문에 How do you assign a lambda to a variable in Java 8?

답변을 인용 단락은 당신이 할 수 없다고 정확히 무슨 일이 좋습니다.

그래서 기사의 정보가 잘못 되었습니까? 아니면 여기에있는 내용을 잘못 읽었습니까?

감사합니다.

+2

'람다'에 동일한 람다를 할당하고 정렬 호출에 사용하면 ... –

답변

16

기사와 모순되는 연결된 SO 답변에는 아무 것도 표시되지 않습니다.

유형 시스템의 규칙은 기능적 인터페이스 유형의 객체에 적용됩니다.변수를 BiFunction<String,String,Integer> bifunc으로 선언하면 Comparator<String>의 하위 유형이 아니기 때문에 Comparator<String>이 필요한 메소드로 전달할 수 없습니다. BiFunction<String,String,Integer>Comparator<String>의 하위 유형이 아니기 때문입니다.

기능 유형이 모든 일반적인 규칙을 준수한다는 사실 때문에이 새로운 기능을 최소한의 섭동으로 추가 할 수 있습니다.

그리고 당신이 BiFunction 밖으로 Comparator을하고자하는 경우에 당신이해야 할과 같이 ::apply를 추가 할 수 있습니다 :

BiFunction<String,String,Integer> bifunc = (a,b) -> 
           Integer.compare(a.length(), b.length()); 

Arrays.sort(array, bifunc::apply); 
2

이 기사는 BiFunction 유형의 객체를 기준으로 분류 할 수 없지만 항상 Comparator을 사용할 수 있다는 의미에서 정확합니다. 그러나 어이, 그들은 둘 다 동일한 몸을 소유 할 수있다. 예를 들어 라인 4에서 위

private static void sort(Comparator<String> ls){ 
     Arrays.sort(someArray, ls); 
} 

Comparator<String> comp = (String f1, String f2) -> Integer.compare(f1.length(), f2.length()); 
sort(comp); 

BiFunction<String, String, Integer> func = (String f1, String f2) -> Integer.compare(f1.length(), f2.length()); 
sort((String f1, String f2) -> Integer.compare(f1.length(), f2.length())); //line-4 

sort(func) // compiler error 

, 당신은 func와 정확히 동일한 람다을 통과 할 수 있습니다. 하지만 여전히 funcsort에 전달할 수 없습니다. java8의 Lambdas는 일부 FunctionalInterface 구현입니다. Functional Interfaces는 참조 유형을 기반으로 유형을 가져옵니다. 초기화시 동일한 람다가 BiFunction 또는 Comparator 일 수 있습니다.

하지만 람다가 생성되고 유형이되면 유형을 변경할 수 없습니다. 따라서 func 유형의 BiFunction을 기대하는 정렬로 전달할 수 없습니다. Comparator

1

기사가 올바른지. 예 : BiFunction ~ Comparator.

Brian Goetz가 작성한 great article이 좋은 방법으로 문제를 설명합니다.

컴파일러 람다 식 발생

, 그것은 제 저하 (desugars) 인수 목록을 반환 타입 매치

따라서 람다 발현 람다 될 수있는 방법으로, λ 체 입니다.하지만 그게 무슨 뜻입니까? 기본적으로 lamdba와 어떻게 든 일치하는 새로운 방법이 만들어 질 수 있습니다.

class A { 
    public void foo() { 
     List<String> list = ... 
     list.forEach(s -> { System.out.println(s); }); 
    } 
} 

위의 코드는 가 이런 식으로을 desugared 될 것입니다 : 그래서

class A { 
    public void foo() { 
     List<String> list = ... 
     list.forEach([lambda for lambda$1 as Consumer]); 
    } 

    static void lambda$1(String s) { 
     System.out.println(s); 
    } 
} 

BiFunctionComparator의 경우. 제공된 람다 모두에 할당 될 수있다 : 일단 람다는 다음이 람다 식 일치하더라도 재 할당 할 수없는 형태 (BiFunction 또는 Comparator)에 할당 된

// Assign the lambda to a BiFunction 
BiFunction<String, String, Integer> b1 = 
     (first, second) -> Integer.compare(first.length(), second.length()); 

// Assign the lambda to a Comparator 
Comparator<String> c1 = 
     (first, second) -> Integer.compare(first.length(), second.length()); 

// But, once the lambda has been assigned to a type you can not reassign it 
BiFunction<String, String, Integer> b2 = c1; // <-- Error 

참고.

+0

이 기사에서 코드 스 니펫을 인계하면 실제 API로 업데이트 할 수 있습니다. 'Block '은 당시'소비자 '이되었습니다. 오래된 이름을 붙이면 독자가 역사를 인식하지 못하게 될 수 있습니다. – Holger

+0

@Holger 다시 한번 감사드립니다. 답변을 업데이트했습니다. – wassgren