메소드 참조에 대해 람다와 비교하며 설명이 되어있다.
람다에서 이런 경우가 존재한다고 가정을 해보자
(String s) -> Integer.parseInt(s);
형식 추론에서 이야기 한 것과 같이 s 인자의 타입은 함수형 인터페이스의 대상형식 및 추상메소드를 통해 확인이 가능하다.
즉 parseInt에 파라미터가 String 타입인 것, 입력 파라미터가 String s인 것을
형식 추론을 통해 알 수 있는 것이다.
그렇기 때문에 이 2가지 과정을 없애면Integer.parseInt
가 되고, 최종적으론
(Integer::parseInt)
이런 식으로 표현이 가능하다. 지금 보고 있는 것이 메소드 참조이다.
즉 메소드 참조는 메소드명(parseInt)를 참조함으로써 가독성을 높일 수 있다.
(여담) 방식을 이해하는게 상당히 오래 걸렸다. 메소드 참조에서 람다로 변환하는 것을 여러번 해보면 이해가 조금 될 수 있다.
- 정적 메소드 참조(위의 예시와 동일 parseInt는 static 메소드)
Integer(className)::parseInt(staticMethodName)
- 다양한 형식의 인스턴스 메소드 참조
Function<String, Integer> func = (String s) -> s.length(); Function<String, Integer> func = String(className)::length(methodName);
- 기존 객체의 인스턴스 메서드 참조(잘 안쓰는 편)
public class Main { public static void main(String[] args) throws Exception { Main main = new Main(); Consumer<Integer> consumer = (Integer i) -> main.func(); Consumer<Integer> consumer = main(객체를 할당받은 지역변수)::func(객체 메소드); } private void func(Integer integer) { } }
Supplier<Node> s = Node::new; Node s1 = s.get(); Function<Integer, Node> func = Node::new; (Integer 파라미터가 존재하는 생성자 객체 인스턴스 생성)
- Comparator 조합 : reversed(내림차순), thenComparing(두번째 비교자를 비교)
- Predicate 조합 : and(and 조건), or(or 조건), negate(기존 객체에 반대되는 데이터 찾기)
- Funcation 조합(f(x), g(x)가 존재한다 가정) :
- f.andThen(g) : g(f(x))
- f.compose(g) : g(f(x))
결론적으로 말하면 람다보다 상당히 이해하는데 시간이 오래걸렸다.
책만 보고 안되서 메소드 참조의 작동원리는 구글링 하면서 좀 찾아봤다.
메소드 참조의 경우 계속 연습을 해보면서 익숙해지도록 노력해야겠다.