[작성일: 2023. 02. 12]
람다식(Lambda Expression)
- 함수(메서드)를 간단한 식으로 표현하는 방법
- 익명 함수(이름이 없는 함수, anonymous function)
- 람다식은 익명 함수가 아닌 익명 객체임!
- 함수와 메서드의 차이
- 근본적으로 동일하나 함수는 일반적 용어, 메서드는 객체지향개념 용어
- 함수는 클래스에 독집적이며 메서드는 클래스에 종속적임.
- 람다식(익명 객체)을 다루기 위한 참조변수가 필요함.
class ex {
public static void main(String[] args) {
// Object obj = (a, b) -> a > b ? a : b; // 람다식, 익명객체
Object obj = new Object() {
int max(int a, int b) {
return a > b ? a : b ;
}
};
int value = obj.max(3,5); // 에러. 함수형 인터페이스 필요
}
}
람다식 작성하기
- 메서드의 이름과 반환타입을 제거하고 '->'를 블록{} 앞에 추가함.
(int a, int b) -> { return a > b ? a : b; }
- 반환값이 있는 경우 식이나 값만 적고 return문 생략 가능( 끝에 ; 안 붙임.)
- 블록 안의 문장이 하나뿐인 경우, 괄호 {} 생략 가능(끝에 ; 안 붙임)
- 하나뿐인 문장이 return문이면 괄호 {} 생략 불가
(int a, int b) -> a > b ? a : b
(int i) -> System.out.println(i)
(int a, int b) -> { return a > b ? a : b; }
- 매개변수의 타입이 추론 가능하면 생략가능(대부분의 경우 생략 가능)
- 매개변수가 하나인 경우, 괄호 () 생략 가능(타입이 없을 때만)
(a, b) -> a > b ? a : b
a -> a * a
람다식 작성 예
메서드 | 람다식 |
int max(int a, int b) { return a > b ? a : b; } | (int a, int b) -> a > b ? a : b (a, b) -> a > b ? a : b |
int printVar(String name, int i) { System.out.println(name+"="+i); } | (String name, int i) -> System.out.println(name + "="+i) (name, i) -> System.out.println(name + "="+i) |
int squre(int x) { return x * x; } | (int x) -> x*x x-> x * x |
int roll() { return (int)(Math.random() * 6); } | () -> (int)(Math.random() * 6) |
함수형 인터페이스
- 단 하나의 추상 메서드만 선언 된 인터페이스
- 함수형 인터페이스 타입의 참조변수로 람다식을 참조할 수 있음.
- 단, 함수형 인터페이스의 메서드와 람다식 매개변수 개수와 반환타입이 일치해야 함.
class ex {
public static void main(String[] args) {
MyFunction f = (a, b) -> a > b ? a : b; // 람다식
int value = f.max(3,5);
System.out.println(value);
}
}
@FunctionInterface
interface MyFunction {
int max(int a, int b);
}
메서드 참조(method reference)
- 하나의 메서드만 호출하는 람다식은 메서드 참조로 간단히 할 수 있음.
- 클래스 이름::메서드 이름
- 함수형 인터페이스에 정보가 다 있기 때문에 메서드 참조가 가능함.
종류 | 람다 | 메서드 참조 |
static 메서드 참조 | (x) -> ClassName.method(x) | ClassName::method |
인스턴스 메서드 참조 | (ojb.x) -> obj.method(d) | ClassName::method |
impor java.util.function.Function
class ex {
public static void main(String[] args) {
// Function<String, Integer> f = (String s) -> Integer.parseInt(s);
Function<String, Integer> f = Integer :: ParseInt; // 메서드 참조
System.out.println(f.apply("100") + 200);
}
}
생성자의 메서드 참조
class ex {
public static void main(String[] args) {
// Supplier는 입력X, 출력O
// Supplier<MyClass> s = () -> new MyClass();
// Supplier<MyClass> s = MyClass :: new; // 메서드 참조
Function<Integert, MyClass> s = (i) -> new MyClass(i);
Function<Integer, MyClass> s = MyClass :: new;
MyClass mc = s.apply(100);
System.out.println(mc.iv);
System.out.println(f.apply(100).iv);
}
}
class MyClass {
int iv;
MyClass(int iv) {
this.iv = iv;
}
}
배열과 메서드 참조
Function<Integer, int[]> f = x -> new int[x]; // 람다식
Function<Integer, int[]> f2 = int[] :: new; // 메서드 참조
class ex2 {
public static void main(String[] args) {
Function<Integer, int[]> f2 = (i) -> new int[i];
Function<Integer, int[]> f2 = int[] :: new;
System.out.println(f2.apply(100).length);
}
}
class MyClass {
int iv;
MyClass(int iv) {
this.iv = iv;
}
}
🐣 해당 게시글은 자바의 정석(남궁성 님) 영상으로 함께 공부하며 요약/정리한 글입니다.
🐣 입문 개발자가 작성한 글이므로 틀린 내용이나 오타가 있을 수 있습니다.