메소드 참조
메소드 참조란, 메소드를 참조하여 매개변수의 정보 및 리턴 타입을 알아내어 람다식에서 불필요한 매개변수를 제거하는 것이다.
예를들어 아래와 같은 코드가 있을 때, 람다식은 단순히 두개의 값을 Math.max() 메소드의 매개값으로 전달하는 역할만 한다.
( o1 , o2 ) -> Math.max(o1, o2);
이는 메소드 참조를 통해 아래와 같이 간결하게 변환할 수 있다.
IntBinaryOperator operator = Math :: max;
정적 메소드와 인스턴스 메소드 참조
정적메소드와 인스턴스 메소드를 참조하는 방식은 다음과 같다.
- 정적 메소드 - 클래스::메소드
- 인스턴스 메소드 - 참조변수::메소드
import java.util.function.IntBinaryOperator;
public class Calculator {
public static int staticMethod(int x, int y){
return x + y;
}
public int instanceMethod(int x, int y){
return x + y;
}
}
public class MethodReferencesExample {
public static void main (String[] args){
IntBinaryOperator operator;
// # 1. static method 참조
operator = (x, y) -> Calculator.staticMethod(x, y);
System.out.println("static method 참조 result : " + operator.applyAsInt(1, 2));
// 1.1 static method를 메소드 참조를 통해 참조
operator = Calculator::staticMethod;
System.out.println("method 참조를 통한 static method 참조 result : " + operator.applyAsInt(3, 4));
// #2. instance method 참조
Calculator obj = new Calculator();
operator = (x, y) -> obj.instanceMethod(x,y);
System.out.println("instancd method 참조 result : " + operator.applyAsInt(5, 6));
// #2.1
operator = obj::instanceMethod;
System.out.println("method 참조를 통한 instance method 참조 result : " + operator.applyAsInt(7, 8));
}
}
매개변수의 메소드 참조
클래스의 정적 메소드는 클래스::staticMethod로, 인스턴스의 메소드는 인스턴스명::instanceMethod로 참조한다고 하였지만,
클래스::instanceMethod를 사용함으로써 람다식의 외부 클래스 멤버인 메소드를 호출하는 것이 아닌, 람다식에서 제공되는 매개변수의 메소드를 호출 할 수 있다.
import java.util.function.ToIntBiFunction;
public class ArgumentMethodReferenceExample {
public static void main ( String[] args ){
ToIntBiFunction<String, String> function ;
function = (a, b) -> a.compareToIgnoreCase(b);
print(function.applyAsInt("Java8" , "JAVA8"));
// String의 인스턴스 메소드인 compareToIgnoreCase를 호출
// 이때 사용된 함수적 인터페이스는 String 2개를 매개값으로 받고 int를 리턴하는 ToIntBiFunction이다.
function = String::compareToIgnoreCase;
print(function.applyAsInt("Java8" , "JAVA8"));
}
public static void print(int order){
if(order < 0 ){
System.out.println("사전순으로 먼저 옵니다.");
}else if( order == 0){
System.out.println("동일한 문자입니다.");
}else{
System.out.println("사전순으로 나중에 옵니다.");
}
}
}
생성자 참조
단순히 객체를 생성하고 리턴하도록 구성된 람다식도 생성자 참조로 대체될 수 있다.
(a, b) -> { return new Clazz(a,b);}
//아래와 같이 대체 가능
Clazz::new
아래의 코드를 통해 생성자는 Function API에서 넘겨주는 인자 수에 따라서 호출됨을 확인할 수 있다.
import java.util.function.BiFunction;
import java.util.function.Function;
// #1. Member Class
public class Member {
private String name;
private String id;
public Member(String id){
System.out.println("member(string id) 실행");
this.id = id;
}
public Member(String id, String name){
System.out.println("member(String id, String name) 실행");
this.id = id;
this.name = name;
}
public String getName() { return this.name ;}
public String getId() { return this.id;}
}
// #2. Member의 생성자 참조
public class ConstructorReferencesExample {
public static void main ( String [] args) {
// # 3. String을 Member 형으로 변환하는 Function에서 Member의 매개 1개를 가지는 생성자 호출
Function<String, Member> function = Member::new;
Member member = function.apply("angel");
// #4. BiFunction API에서 매개 2개를 가지는 생성자 호출
BiFunction<String, String, Member> function2 = Member::new;
Member member2 = function2.apply("신천사" , "angel2");
}
}
'Study > Java' 카테고리의 다른 글
자바 기본서를 다시 읽다. 8 - 스트림의 중간처리 메소드 (0) | 2022.04.06 |
---|---|
자바 기본서를 다시 읽다. 7 - 스트림의 개념과 파이프라인 (0) | 2022.04.05 |
자바 기본서를 다시 읽다. 5 - 함수적 인터페이스의 Default Method (0) | 2022.03.27 |
자바 기본서를 다시 읽다. 4 - 표준 API의 함수적 인터페이스 (0) | 2022.03.16 |
자바 기본서를 다시 읽다. 3 - 로컬클래스와 익명객체, 그리고 람다식 (2) (0) | 2022.03.15 |