* 람다식(Lambda Expression)
- 함수(메서드)를 간단한 식으로 표현하는 방법/ 익명 함수(anonymous function) 반환 타입, 이름을 지우기 때문에
- 함수 vs 메서드 : 클래스에 독립적이면 함수, 클래스에 종속적이면 메서드
* 람다식 작성하기
1. 메서드의 이름과 반환 타입을 제거하고 ->를 블록{} 앞에 추가.
2. 반환 값이 있는 경우, 식이나 값만 적고 return문 생략 가능 (끝에 ; 도 생략)
3. 매개변수의 타입이 추론 가능하면 생략 가능 (대부분의 경우 생략 가능)
int max(int a, int b){
return a>b ? a : b;
}
(a,b) -> a>b ? a : b
- 람다식 작성 시 주의사항
1. 매개변수가 하나인 경우 괄호 생략 가능
2. 블록 안의 문장이 하나뿐일 때, 괄호 생략 가능
** 람다식은 익명의 객체이다! 사실 위 람다식은 아래의 객체를 선언하면서 호출하는 것.
Object O = new Object(){
int max(int a, int b){
return a>b ? a : b;
}
}
int value = o.max(3,5) // 불가, object에는 max가 없음.
람다식의 참조 변수의 타입은? 람다식의 객체를 선언하려면 참조 변수가 필요한데,
Object로 하면, Object엔 max라는 메서드가 없기 때문에 사용 불가,,
이때 함수형 인터페이스 사용!
* 함수형 인터페이스
- 단 하나의 추상 메서드만 선언된 인터페이스/ 람다식을 다루기 위해 사용됨.
interface MyFunction{
public abstract int max(int a, int b);
}
위 인터페이스를 사용해 익명 클래스 선언, 객체 생성 동시에 하기
MyFunction f = new MyFunction(){
public int max(int a, int b){
return a>b ? a : b;
}
};
// 이걸 람다식으로 작성하면
MyFunction f = (a,b) -> a>b ? a:b; // 여기에 메서드의 이름이 없는데 (max) 인터페이스에서 만든 이름을 사용하면 됌
int value = f.max(3,5); // ok. MyFunction에 max() 가 있음
* 함수형 인터페이스 example
- 익명 객체를 람다식으로 대체 (sort)
List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "aaa");
// 정렬하기 원래 sort 메서드의 매개변수로 Comparator를 넣어주는데, 이 것의 오버라이딩이 필요함.
Collections.sort(list, new Comparator<String>(){
public int compare(String s1, String s2){
return s2.compareTo(s1);
}
});
// Comparator는함수형 인터페이스로 @FunctionalInterface 가 붙어있음. 이를 람다식으로 바꾸면
Collections.sort(list, (s1, s2) -> s2.compareTo(s1));
* 함수형 인터페이스 타입의 매개변수, 반환 타입
- 함수형 인터페이스 타입의 매개변수
: 메서드가 매개변수에 함수형 인터페이스가 있으면 이를 람다식으로 받겠다는 의미!
@FunctionalInterface
interfaace MyFunction{
void myMethod();
}
void aMethod(MyFunction f){
f.myMethod();
}
Myfunction f = () -> System.out.println("myMethod()");
aMethod(f);
- 함수형 인터페이스 타입의 반환 타입
MyFunction myMethod(){
MyFunction f = () -> {};
return f
}
* 메서드 참조(method reference)
- 하나의 메서드만 호출하는 람다식은 '메서드 참조' 로 더 간단히 할 수 있다.
- static 메서드 참조
Integer method(String s){ // 클래스에 들어있는 메서드
return Integer.parseInt(s);
}
// 원래 호출할 땐 클래스의 객체를 통해 호출
int result = obj.method("123");
// 이런 번거로움 해결하기 위해 static메서드가 있음. 바로 호출 가능
int result = Integer.parseInt("123");
// 이를 람다식으로 더 간단하게
Function<String, Integer> f = (String s) -> Integer.parseInt(s);
// 이를 메서드 참조로 더 간단하게
Function<String, Integer> f = Integer::parseInt; // 메서드 참조
- 생성자와 메서드 참조
Supplier<MyClass> s = () -> new MyClass(); // 람다식
Supplier<MyClass> s2 = MyClass::new; // 메서드 참조
Function<Integer, MyClass> s = (i) -> new MyClass(i); // 람다식
Function<Integer, MyClass> s2 = MyClass::new; // 메서드 참조
- 배열과 메서드 참조
Function<Integer, int[]> f = (i) -> new int[i]; // 람다식
Function<Integer, int[]> f2 = int[]::new; // 메서드 참조
'코딩 > JAVA 공부' 카테고리의 다른 글
| [JAVA] 자바의 정석 _ Optional<T> (0) | 2022.10.28 |
|---|---|
| [JAVA] 자바의 정석 _ java.util.function 패키지 (0) | 2022.10.28 |
| [JAVA] 자바의 정석 _ 쓰레드 (0) | 2022.10.20 |
| [JAVA] 자바의 정석 _ 열거형(enum) / 애너테이션 (0) | 2022.10.18 |
| [JAVA] 자바의 정석 _ Generics (0) | 2022.10.17 |