List<Company> companiesHasCafeteria= filter(list, (Company company)-> company.hasCafeteria());
람다는 사용되는 콘텍스트(Context)를 이용해 람다의 형식(Type)을 추론할 수 잇는데, 어떤 콘텍스트에서 제공될꺼라 기대되는 람다 표현식의 형식을 대상 형식(Target Type) 이라 한다.
위 코드는 사내식당을 보유한 회사 목록을 필터링하는 코드인데, 위 코드가 어떤 과정으로 형식 확인을 하는지에 대해 알아보자.
람다 표현식의 형식 검사 과정
Prediate<Company> p
는 boolean test(T t)
라는 하나의 추상 메서드를 정의하는 함수형 인터페이스이다.(Company company)→ company.hasCafeteria()
는 Company → boolean의 형태를 띄고있기에 유효하며 이렇게 형식 검사는 성공적으로 완료된다.이러한 과정들을 보면 대상 형식(target typing)이 같다면, 같은 람다 표현식을 다른 함수형 인터페이스에서도 활용할 수 있다.
Comparator<Apple> c1 = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
ToIntBiFunction<Apple, Apple> c2 = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
BiFunction<Apple, Apple, Integer> c3 = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
🚀참고: void 호환 규칙
람다의 바디에 일반 표현식이 있을 경우 void를 반환하는 함수 디스크립터와 호환된다. Predicate<String> p = s → list.add(s); //return boolean Consumer<String> b = s → list.add(s);// return Void 위 코드에서 람다의 바디인 list.add(s)는 Consumer 콘텍스트(T→void)가 기대하는 void 대신 boolean을 반환하지만 유효하다.