자바(SE)

[람다표현식]메서드 참조와 생성자 참조

  • -

이번 포스트에서는 람다식을 이용한 코드 축약의 최종판으로 메서드 참조와 생성자 참조에 대해서 살펴보자.

 

메서드 참조

 

메서드 참조란?

메서드 참조는 다른 코드에 전달하려는 동작을 수행하는 코드가 딸랑 어떤 메서드 하나만 실행하면 될 때 사용된다. 메서드 참조를 위해서는 :: 연산자를 이용하는데 <소유자>::<메서드이름>의 형태로 사용한다.

 

파라미터_클래스::파라미터_클래스의_메서드

예를 들어 문자열의 배열이 있고 이에 대한 정렬 코드를 작성해보자.

이때 두 문자열을 비교할 때 파라미터인 String 클래스에 정의된 instance 메서드인 compareTo를 사용할 수 있다. 그리고 특별히 할 일이 없다면 아래처럼 실행문에서는 딸랑 o1.compareTo(o2)가 작성된다.

String[] langs = { "Phyhon", "C", "java", "JavaScript" };

Arrays.sort(langs, (o1, o2) ->  o1.compareTo(o2));

이런 경우 아래와 같이 축약해서 작성할 수 있다.

Arrays.sort(langs, String::compareTo);

이때 전달된 파라미터 중 첫 번째(o1)이 메서드의 소유자, 두 번째 파라미터(o2)는 메서드 실행 시 파라미터로 전달된다.

메서드를 참조할 때 반드시 위의 경우처럼 instance method일 필요는 없다. static 메서드 역시 동일하게 사용할 수 있다. 다음예는 파라미터인 Integer를 정렬하기 위해서 instance method인 compareTo와 static method인 compare 메서드를 사용하는 예를 보여준다. static method를 사용할 때에는 모든 파라미터가 메서드로 전달된다.

 

Integer [] nums = {1,7,3,4,5};
Arrays.sort(nums, (num1, num2)-> num1.compareTo(num2));       // instance method
Arrays.sort(nums, Integer::compareTo);    

Arrays.sort(nums, (num1, num2)-> Integer.compare(num1, num2)); // static method
Arrays.sort(nums, Integer::compare);

 

객체::메서드

경우에 따라서는 파라미터 클래스가 아닌 다른 클래스에 선언된 메서드를 사용해야하는 경우도 존재한다. 이런 경우는 객체::메서드의 형태로 사용한다.

다음의 코드는 strs가 가지고 있는 요소들을 모두 출력하기 위해서 forEach를 사용하는데 Consumer에서는 System.out 즉 PrintStream 이 가지고 있는 println 메서드만 사용하고 있다.

List<String> strs = Arrays.asList("Hello", "Lambda");

strs.forEach(str -> System.out.println(str));

이런 경우 아래와 같이 축약해볼 수 있다. 여기서 소유자 객체는 PrintlnStream 타입이고 이녀석의 메서드 println에 lambda 식의 파라미터가 전달된다.

strs.forEach(System.out::println);

 

줄어드니까 정말 좋다!!

 

여기까지 람다식을 활용하는 다양한 형태에 대해서 살펴봤는데 최초 anonymous inner class를 활용했을 때에 비하면 코드가 확 줄어든 것이 보인다.

List<String> strs = Arrays.asList( "Lambda", "Hello","world");

strs.sort(new Comparator<String>() {
    public int compare(String o1, String o2) {
        return o1.compareTo(o2);
    };
});

strs.sort((String o1, String o2) ->{
    return o1.compareTo(o2);
});

strs.sort( (o1, o2) -> o1.compareTo(o2));

strs.sort(String::compareTo);

 

이제는 람다 표현식이 많이 익숙해졌지만 특히 처음 자바를 접하거나 함수형 프로그래밍에 익숙하지 않은 경우는 축약된 식을 보면 맨붕이고 어디서 디버깅을 해야할지도 난간해하는 경우를 많이 보아왔다.

개인적인 생각으로는 모든 식을 바로 줄여서 사용하려는 욕심을 버리고 일단은 이해하기 쉬운 레벨의 코드를 작성하는 것을 권장한다.  중요한건 코드가 얼마나 짧은가가 아니라 얼마나 이해하고 작성하고 있는가니까..

 

'자바(SE)' 카테고리의 다른 글

[자바]JVM Heap Memory size  (0) 2022.08.14
[Generic]raw 타입을 사용하지 말자.  (0) 2022.07.24
[람다표현식]functional interface  (0) 2022.07.13
[람다표현식]Lambda 표현식  (0) 2022.07.11
[람다표현식]inner class  (0) 2022.07.11
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.