일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- find
- 필드의다형성
- 문자열을 배열
- ZipInputStream
- 인터페이스
- 오버라이딩
- java
- 공백 처리
- 자동타입변환
- 정적메소드
- 구현클래스
- 상수필드
- 요소
- 선택한요소
- 익명구현객체
- 상속
- 인스턴스메소드
- 생성자참조
- 람다식
- 타깃타입
- 배열을 문자열
- 인터페이스의역할
- 자바
- 객체타입확인
- 추상메소드
- 디폴트메소드
- jQuery
- 매개변수참조
- createTempFile
- map에서key와value
- Today
- Total
코드지우개
람다식 ⑤ 본문
메소드 참조 (Method references)
메소드를 참조해서 매개변수의 정보 및 리턴 타입을 알아내서 람다식에서 불필요한 매개변수를 제거하는 것이 목적이다.람다식은 종종 기존 메소드를 단순하게 호출만 하는 경우가 있다.
(left, right) -> Math.max(left, right);
Math::max; <----- 메소드 참조
매개변수가 2개가 주어지고 Math.max()를 호출할 때 2개의 매개변수를 넣어주었다.
실행 부를 보면 단순하게 메소만 호출하고 있다.
이 경우에 매 개값 2개가 메소드 호출할 때 사용하게 되는데 매개변수에도 left, right를 적고 메소드 호출할 때 또 left, right를 적게 돼서 불필요한 중복이 발생하기 때문에 이를 해결하게 위해 메소드 참조를 사용하면 된다.
메소드 참조도 람다식과 마찬가지로 인터페이스의 익명 구현 객체로 생성된다.
- 타깃 타입에서 추상 메소드의 매개변수 및 리턴 타입에 따라 메소드 참조도 달라진다.
- ex) IntBinayOperator 인터페이스는 두 개의 int 매 개값을 받아 int 값을 리턴하므로 동일한 매 개값과 리턴 타입을 갖는 Math 클래스의 max() 메소드를 참조할 수 있다.
IntBinaryOperator operator = Math::max;
정적 메소드와 인스턴스 메소드 참조
정적 메소드를 참조할 때와 인스턴스 메소드를 참조할 때 좀 다르게 사용된다.
정적 메소드를 참조할 때는 '클래스::메서드'로 작성하면 되고 인스턴스 메소드를 참조할 때는 '참조 변수::메서드'로 작성하면 된다.
public class Calculator{
public static int staticMethod(int x, int y){
return x + y;
}
public int instanceMethod(int x, int y){
return x + y;
}
}
Calculator라는 클래스에 정적 메소드와 인스턴스 메소드가 있을 때 메소드 참조를 하려면 아래 코드처럼 하면 된다.
IntBinaryOperator operator;
//정적 메소드 참조
operator = (x,y) -> Calculator.staticMethod(x,y);
System.out.println("결과1: " + operator.applyAsInt(1,2));
↓
operator = Calculator::staticMethod;
System.out.println("결과2: " + operator.applyAsInt(3,4));
//인스턴스 메소드 참조
Calculator obj = new Calculator();
operator = (x,y) -> obj.instanceMethod(x,y);
System.out.println("결과3: " + operator.applyAsInt(5,6));
↓
operator = obj::instanceMethod;
System.out.println("결과4: " + operator.applyAsInt(7,8));
//출력
결과1: 3
결과2: 7
결과3: 11
결과4: 15
매개변수의 메소드 참조
(a,b) -> {a.instanceMethod(b);}
위에 코드를 보면 2개의 매개변수를 받아서 실행부에서 첫 번째 매개변수 a에 instanceMethod 메소드를 호출을 해서 두 번째 매 개값인 b를 instanceMethod 메소드의 매 개값으로 사용했다.
이와 같은 람다식을 메소드 참조로 표현하자면 '클래스::instanceMethod'로 표현할 수 있다.
이때 '클래스'는 a의 타입이 된다. a의 타입이 String일 경우 클래스는 String이 된다.
public static void main(String[] args){
ToIntBiFunction<String, String> function;
/*
compareToIgnoreCase : a가 b보다 사전순으로 먼저 오면 음수 같으면 0 뒤에오면 양수
IgnoreCase는 대소문자를 가리지 않고 알파벳만으로 비교하겠다.
*/
function = (a,b) -> a.compareToIgnoreCase(b);
print(function.applyAsInt("java8", "JAVA8")); // function.applyAsInt("java8", "JAVA8") 값 : 0
↓
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 클래스(a,b);}
위에 코드를 보면 2개의 매개변수를 받아서 실행부에서 new 연산자를 사용해서 클래스에 객체를 생성하고 이때 매 개값으로 제공된 a, b를 생성자에 매 개값으로 제공하고 이렇게 생성된 객체를 리턴하고 있다.
이와 같이 실행부에 객체를 생성하고 리턴하는 코드만 있는 람다식을 생성자 참조로 표현하자면 '클래스::new'로 표현할 수 있다.
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;
}
위에 코드처럼 Member 클래스에 id를 받는 생성자와 name, id를 받는 생성자가 있을 때 생성자 참조를 하려면 아래 코드처럼 하면 된다.
Function<String, Member> function1 = Member::new;
Member member = function1.apply("angel"); //Member(String id) 실행
BiFunction<String, String, Member> function2 = Member::new;
Member member2 = function2.apply("천사","angel"); //MEmber(String name, String id) 실행
'java' 카테고리의 다른 글
File을 MultipartFile 타입으로 변환 (0) | 2023.09.05 |
---|---|
RestTemplate.execute()를 사용하여 File타입으로 리턴 받기 (0) | 2023.09.05 |
람다식 ④ (0) | 2023.06.05 |
람다식 ③ (0) | 2023.06.05 |
람다식 ② (0) | 2023.06.05 |