[Java 8] 메서드 레퍼런스(Method Reference) 사용 방법 4가지와 간단한 사용예제

콜론 두개(::)가 있으면 메서드 레퍼런스를 사용하는 것이다.

 

예제에 사용될 Greeting 클래스

public class Greeting {
    private String name;

    public Greeting() {
    }

    public Greeting(String name) {
        this.name = name;
    }

    public String hello(String name) {
        return "hello " + name;
    }

    public static String hi(String name) {
        return "hi " + name;
    }
}

1. 스태틱 메서드 참조

Greeting 클래스에 있는 static 메서드 참조 방법

UnaryOperator<String> hi = Greeting::hi;
//UnaryOperator<String> hi = (s) -> "hi " + s; 위와 동일한 기능

2. 특정 객체의 인스턴스 메서드 참조

Greeting greeting = new Greeting();
UnaryOperator<String> hello = greeting::hello;

3. 생성자 메서드 참조

Supplier<Greeting> newGreeting = Greeting::new; //Supplier 객체 생성
Greeting greeting = newGreeting.get(); //실질적 Greeting 객체 생성
        
  
Function<String, Greeting> hyunsuGreeting = Greeting::new;
Greeting hyunsu = hyunsuGreeting.apply("hyunsu");

newGreeting은 Supplier 인스턴스 이고 실질적으로 Greeting 객체 생성은 “Greeting greeting = newGreeting.get()” 통해서 된다. 그리고 인자값이 없으므로 매개변수 없는 생성자를 통해서 인스턴스가 생성된다.

hyunsuGreeting 객체는 Function<매개변수, 리턴값>함수 인터페이스를 통해서 만들어 졌으므로 매개변수값이 존재한다. 그래서 String타입의 매개변수가 있는 생성자를 통해서 인스턴스가 생성된다.

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

String[] names = {"hyunsu", "java", "spring"};

//Comparator가 함수형 인터페이스 이기 때문에 람다로 변경 할 수 있다.
Arrays.sort(names, new Comparator<String>() {
       @Override
       public int compare(String o1, String o2) {
                return 0;
   }
});

//람다로 변경할수 있는건 레퍼런스로 변경 가능하다.
Arrays.sort(names, (o1, o2) -> 0);

//람다는 메서드 레퍼런스를 쓸 수 있다.
//문자열과 문자열을 비교해서 int값을 return.
//스태틱 메서드 참조가 아닌 임의의 객체의 인스턴스 참조한 경우이다.
Arrays.sort(names, String::compareToIgnoreCase);

자바 1.8부터 Compartor 인터페이스가 함수형 인터페이스로 변경되었다. 그래서 람다식으로 표현해서 사용이 가능하고 람다로 변경한건 메서드 레퍼런스로 사용할 수 있다.

String객체의 compareToIgnoreCase 함수를 메서드 참조로 사용 하여 Comparator가 하는 String 2개를 받아 int를 리턴하는 방식을 사용하였다. 이러한 경우를 임의 객체의 인스턴스 메서드 참조라고 한다.

 

메서드 레퍼런스 활용 예제

ArrayList<String> nameList = new ArrayList<>();
nameList.add("hyunsu");
nameList.add("lufy");
nameList.add("ohgong");
nameList.add("vegeta");
nameList.add("naruto");

//일반적인 forEach 출력
for (String s : nameList) {
    System.out.println(s);
}

//람다로 변경
nameList.forEach(s -> {
    System.out.println(s);
});

//람다는 메서드 레퍼런스로 변경 가능하다.
nameList.forEach(System.out::println);

//k로 시작하는 리스트 지우기
nameList.removeIf(s -> s.startsWith("k"));

//리스트 정렬
nameList.sort(String::compareToIgnoreCase);

//리스트 역정렬
Comparator<String> compareToIgnoreCase = String::compareToIgnoreCase;
nameList.sort(compareToIgnoreCase.reversed());

많이 사용하는 forEach문을 활용하여 리스트 출력과, removeIf() 함수로 조건에 부합하는 리스트 지우기 또 리스트 정렬, 역정렬 방법을 메서드 레퍼런스로 활용한 예제이다.

 

 

참조 : 백기선 더 자바, Java 8 인프런 강의, https://www.inflearn.com/course/the-java-java8

댓글

Designed by JB FACTORY