본문 바로가기
개발 관련 지식/JAVA

람다식 메소드 참조

by 권태일1147 2020. 4. 7.

메소드를 참조해서 매개 변수의 정보 및 리턴 타입을 알아내어, 람다식에서 불필요한 매개 변수를 제거하는 것이 목적이다.

(left, right) -> Math.max(left, right); // 를 매개변수를 제거해서 참조하는 것으로 바꾸면
Math :: max; // 로 바꿀 수 있다.

 

정적 메소드 참조

클래스 이름 :: 메소드

Class :: method;

 

인스턴스 메소드 참조

먼저 객체를 생성하고, 객체를 참조하는 변수 :: 메소드

Class class = new Class();
class :: method;

 

정적 메소드와 인스턴스 메소드 참조 예시

// Calculator.java

public class Calculator {
    public static int staticM(int x, int y) {
        return x + y;
    }
    
    public int instanceM(int x, int y) {
        return x + y;
    }
}

 

// Main.java

import java.util.function.IntBinaryOperator;

public class Main {
    public static void main(String[] args) {
        IntBinaryOperator operator;
        
        // 정적 메소드 참조
        operator = (x, y) -> Calculator.staticM(x, y);
        System.out.println(operator.applyAsInt(10, 20));
        
        operator = Calculator :: staticM;
        System.out.println(operator.applyAsInt(10, 20));
        
        
        // 인스턴스 메소드 참조
        Calculator calc = new Calculator();
        operator = (x, y) -> calc.instanceM(x, y);
        System.out.println(operator.applyAsInt(20, 30));
        
        operator = calc :: instanceM;
        System.out.println(operator.applyAsInt(20, 30));
    }
}

 

 

 

매개 변수의 메소드 참조

다음과 같이 a 매개 변수의 메소드를 호출해서 b 매개 변수를 매개 값으로 사용할 수도 있다.

(a, b) -> { a.instanceMethod(b); }

이것을 메소드 참조로 표현하면 다음과 같다. a 클래스 이름 :: 메소드 이름

작성 방법은 정적 메소드 참조와 동일하지만, a의 인스턴스 메소드가 참조되므로 전혀 다른 코드가 실행된다.

a의 Class :: instanceMethod;

 

// Main.java

import java.util.function.ToIntBiFunction;

public class Main {
    public static void main(String[] args) {
        ToIntBiFunction<String, String> comp;
        
        comp = (a, b) -> a.compareToIgnoreCase(b);
        print(comp.applyAsInt("Java8", "JAVA8"));
        
        comp = String :: compareToIgnoreCase;
        print(comp.applyAsInt("Java8", "JAVA8"));
    }
    
    public static void print(int order) {
        if(order < 0) { System.out.println("a가 먼저 옵니다"); }
        else if(order == 0) { System.out.println("동일한 문자열입니다."); }
        else { System.out.println("a가 나중에 옵니다."); }
    }
}

compareToIgnoreCase는 String의 인스턴스 메소드로, 사전 순으로 a가 b보다 먼저 오면 음수, 동일하면 0, 나중에 오면 양수를 리턴한다.

사용된 함수적 인터페이스는 두 String 매개값을 받고 int값을 리턴하는 ToIntBiFunction<String, String> 이다.

 

 

 

생성자 참조

생성자를 참조한다는 것은 객체 생성을 의미한다. 단순히 메소드 호출로 구성된 람다식을 메소드 참조로 대치할 수 있듯이, 단순히 객체를 생성하고 리턴하도록 구성된 람다식은 생성자 참조로 대치할 수 있다.

(a, b) -> { return new Class(a, b); }  // 람다식이 단순히 객체 생성 후 리턴하기만 한다.
Class :: new // 이런 식으로 대체 가능

 

생성자 참조를 하는 예시를 보자

// 생성자 오버로딩 Member.java

public class Member {
    private String name;
    private String id
    
    public Member(){
        System.out.println("Member() 실행");
    }
    
    public Member(String id) {
        System.out.println("Member(String id) 실행");
        this.id = id;
    }
    
    public Member(String name, String id) {
        System.out.println("Member(String name, String id) 실행");
        this.name = name;
        this.id = id;
    }
    
    public String getId() { return id; }
}

 

// Main.java

import java.util.function.BiFunction;
import java.util.function.Function;

public class Main {
    public static void main(String[] args) {
        Function<String, Member> function1 = Member :: new; // 생성자 참조
        Member member1 = function1.apply("매개값 1개 짜리 생성자 참조");
        
        BiFunction<String, String, Member> function2 = Member :: new; // 생성자 참조
        Member member2 = function2.apply("매개값 2개 짜리 생성자 참조", "2개 강조");
    }
}

'개발 관련 지식 > JAVA' 카테고리의 다른 글

정적 멤버와 static  (0) 2020.04.08
인스턴스 멤버와 this  (0) 2020.04.08
람다식에서 클래스 멤버와 로컬 변수 사용  (0) 2020.04.07
람다식  (0) 2020.04.07
제네릭 타입의 상속과 구현  (0) 2020.04.06