본문 바로가기
스프링 스터디 (인프런)/더 자바 8

함수형 인터페이스와 람다 - 메소드 레퍼런스

by 백엔드 개발자 2023. 4. 6.

메서드 레퍼런스는 람다 표현식을 구현할 때 사용할 수 있는 방법이다.

람다 표현식의 구현체를 메서드 레퍼런스로 할 수 있다.

 

람다가 하는 일이 기존 메소드 또는 생성자를 호출하는 거라면, 메소드 레퍼런스를 사용해서 매우 간결하게 표현할 수 있다.

 

인스턴스 메서드 : 객체를 생성해야지만 호출이 가능한 메서드이다.

클래스 메서드 : 메서드 앞에 static이 붙은 메서드로, 객체 생성 없이 호출이 가능한 메서드이다.

 

 

 

메소드 참조하는 방법

스태틱 메소드 참조 타입::스태틱 메소드
특정 객체의 인스턴스 메소드 참조 객체 레퍼런스::인스턴스 메소드
임의 객체의 인스턴스 메소드 참조 타입::인스턴스 메소드
생성자 참조 타입::new

     메소드 또는 생성자의 매개변수로 람다의 입력값을 받는다.

     리턴값 또는 생성한 객체는 람다의 리턴값이다.

 

 


/**
 * name을 받는 생성자.
 * @param name
 */
public Greeting(String name) {
    this.name = name;
}

/**
 인스턴스 메서드
 */
public String hello(String name) {
    return "hello " + name;
}

/**
 * 스태틱 메서드
 * @param name
 * @return
 */
public static String hi(String name) {
    return "hi " + name;
}

 

 

1. 스태틱 메서드 레퍼런스

    /**
         * 입력값, 출력값 동일할 때 사용하는 UnaryOperator
         */

        //UnaryOperator<String> hi = (s) -> "hi " + s;
        UnaryOperator<String> hi = Greeting::hi;
        System.out.println(hi.apply("wonsuk"));

스태틱 메서드에서 하는 역할 (파라미터를 hi 문자열 뒤에 붙이는 것)과 람다식 구현체가 같기 때문에

타입::스태틱메서드로 치환하여 사용할 수 있다.

 

 

 

 

2. 인스턴스 메서드 레퍼런스

/**
         * 인스턴스 메서드 레퍼런스
         */
        Greeting greeting = new Greeting();
        UnaryOperator<String> hello = greeting::hello;
        System.out.println(hello.apply("keesun"));

객체 레퍼런스::인스턴스 메서드로 사용할 수 있다.

 

 

 

 

3. 생성자 메서드 레퍼런스

        /**
 *  생성자 참조
 */
        Supplier<Greeting> newGreeting= Greeting::new;
        System.out.println(newGreeting.get());

 

타입::new 로 사용할 수 있다.

아무 파라미터도 없는 생성자를 만든것이기 때문에 아무일도 일어나지 않는다.

 

 

 

 

/**
 * keesunGreeting은 name을 인자로 받는 생성자를 참조하고,
 * newGreeting은 빈값 생성자를 참조한다.
 */
Function<String, Greeting> keesunGreeting = Greeting::new;
Supplier<Greeting> newGreeting = Greeting::new;

Function으로 메서드 레퍼런스를 사용하면, name을 인자로 받는 생성자를 참조할 수 있다.

 

 

 

 

 

 

문자를 받는 생성자 확인해보기

Function<String, Greeting> keesunGreeting = Greeting::new;
Greeting keesun = keesunGreeting.apply("keesun");
System.out.println(keesun.getName());

keesunGreeting.apply로 name값을 인자로 전달하여  Greeting 타입의 리턴값을 받는다.

name을 찍어보면 keesun으로 정상적으로 나오는 것을 확인할 수 있다.

 

 

 

 

 

 

4. 임의의 객체 인스턴스 메서드 참조하기

String[] names = {"keesun", " whiteship", "toby"};
Arrays.sort(names, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return 0;
    }
});

 Arrays.sort(names, (o1, o2) -> 0);

Comparator로 구현한 코드를 람다식으로 변경할 수 있으므로, 메서드 레퍼런스를 사용할 수 있다.

 

타입::인스턴스 메서드

 

 

 

Arrays.sort(names, String::compareToIgnoreCase);
System.out.println(Arrays.toString(names));

 

compareToIgnoreCase : 케이스를 무시하고 두 문자열 비교.

A.compareToIgnoreCase(B) 

A가 B보다 크면 0보다 큰값, 작으면 0보다 작은값, 동일하면 0을 리턴한다.

 

 

 

 

타입의 뜻을 정확히 알고 싶다.

 

 

 

참고

     https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html