람다식
: 함수(메소드)를 하나의 '식(expression)'으로 표현한 것
함수를 간략하고 명확하게 표현할 수 있게 해줌
'익명 함수(anonymous function)' 라고도 함 ( 메소드의 이름과 반환값이 없어짐)
메소드의 매개변수로 전달되어지는 것이 가능
메소드의 결과로 반환 될 수도 있음
람다식으로 인해 메소드를 변수처럼 다루는 것이 가능하게 됨
람다식 작성
ㅡ> 메소드에서 이름과 반환타입을 제거, 매개변수 선언부와 몸통{ } 사이에 '->' 추가하면됨
작성법 | 람다식 | ||
int max(int a, int b) { return a > b ? a : b; } |
ㅡ> | (int a, int b) -> { return a > b ? a: b; } |
|
반환값이 있는 메소드 : 식 이나 값만 적고 return문 생략, 끝에 ; 안붙임 |
(int a, int b) -> { return a > b ? a : b; } | ㅡ> | (int a, int b) -> a > b ? a : b |
람다식에 선언된 매개변수의 타입이 추론 가능한 경우, 생략가능 | (int a, int b) -> a>b ? a : b | ㅡ> | (a,b)-> a > b ? a : b |
선언된 매개변수가 하나뿐인 경우, 괄호( )생략 가능 단, 매개변수의 타입이 있으면 괄호( ) 생략 불가 |
(a) -> a*a (int a) -> a*a |
ㅡ> | a -> a*a //OK int a -> a*a //에러 |
괄호{ }안에 문장이 하나일 때는 괄호{ }생략 가능 이 때, 문장 끝에 ;붙이지 않음 |
(String name, int i) -> { System.out.println(name+"="+i); } |
ㅡ> | (String name, int i) -> System.out.println (name+"="+i) |
람다식은 익명클래스의 객체와 동등함
함수형 인터페이스(Functional Interface)
: 람다식을 다루기 위한 인터페이스
단 하나의 추상메소드만 정의되어 있어야함
interface Myfunction {
public abstract int max(int a, int b);
}
// 위 인터페이스를 구현한 익명 클래스의 객체 생성
My function f = new MyFunction() {
public int max(int a, int b) {
return a > b ? a : b;
}
};
int big = f.max(5,3); // 익명 객체의 메소드를 호출
//익명 객체를 람다식으로 대체 가능
MyFunction f = (int a, int b) -> a > b ? a : b;
int big = f.max(5,3); // 익명 객체의 메소드를 호출
람다식을 참조변수로 다룰 수 있음 ㅡ> 메소드를 통해 람다식을 주고받을 수 있음
( 즉, 변수처럼 메소드를 주고받는 것이 가능)
사실상, 메소드가 아니라 객체를 주고받는 것이라 근본적으로 달라진 것은 없으나 람다식 덕분에 코드가 간결하고 쉬워짐
//함수형 인터페이스 MyFunction정의
@FunctionalInterface //컴파일러가 체크해줌
interface MyFunction {
void myMethod(); //추상 메소드
}
void aMethod(MyFunction f) { // 매개변수의 타입이 함수형 인터페이스
f.myMethod(); // MyFunction에 정의된 메소드 호출
}
...
Myfunction f = () -> System.out.println("myMethod()");
aMethod(f);
//참조변수 없이 직접 람다식을 매개변수로 지정 가능
aMethod(()-> System.out.println("myMethod()")); //람다식을 매개변수로 지정
메소드의 반환타입이 함수형 인터페이스타입이면, 함수형 인터페이스의 추상메소드와 동등한 람다식을 가리키는 참조변수를 반환하거나 람다식을 직접 반환 가능
MyFunction MyMethod() {
MyFunction f = ()->{};
return f; // 이 줄과 윗 줄을 한 줄로 줄이면, return()->{};
}
java.util.function패키지에 일반적으로 자주 쓰이는 형식의 메소드를 함수형 인터페이스로 미리 정의해 놓았음
가능하면 이 패키지의 인터페이스를 활용하는것이 좋음
<자주 쓰이는 가장 기본적인 함수형 인터페이스>
Ex) java.util.function패키지 예제
여러 Predicate(조건식)을 and( ), or( ), negate( )로 연결해서 하나의 새로운 Predicate으로 결합 할 수 있음
static메소드인 isEquals( )는 두 대상을 비교하는 Predicate을 만들때 사용
( isEqual( )의 매개변수로 비교대상을 하나 지정하고, 또 다른 비교대상은 test( )의 매개변수로 지정
함수형 인터페이스를 사용하는 컬렉션 프레임웍 인터페이스
Ex)
메소드 참조
: 람다식이 하나의 메소드만 호출하는 경우, 메소드 참조를 이용하여 람다식을 간략히 할 수 있음
' 클래스이름::메소드이름' 또는 '참조변수::메소드이름'으로 바꿀 수 있음
생성자를 호출하는 람다식도 메소드 참조로 변환할 수 있음
메소드 참조는 람다식을 마치 staitc변수처럼 다룰 수 있게 해줌
Supplier<MyClass> s = () -> new MyClass(); // 람다식
Supplier<MyClass> s = MyClass::new; // 메소드 참조
Function<Integer, MyClass> f = (i) -> newMyClass(i); // 람다식
Function<Integer, MyClass> f2 = MyClass::new; // 메소드 참조
BiFunction<Integer, String, MyClass> bf = (i, s) -> new MyClass(i,s);
BiFunction<Integer, String, MyClass> bf2 = MyClass::new; //메소드 참조
//배열
Function<Integer, int[]> f = x -> new int[x]; // 람다식
FUnction<Integer, int[]> f2 = int[]::new; // 메소드 참조
'TIL (Today I Learned) > Java' 카테고리의 다른 글
TIL 230324(금) 네트워크 (6) | 2023.03.24 |
---|---|
TIL 230322(수) 스트림, 중간연산, Optional<T> ,최종연산 (5) | 2023.03.22 |
TIL 230320(월) 쓰레드, 데몬 쓰레드, 쓰레드 스케줄링, 쓰레드 동기화 (6) | 2023.03.20 |
TIL 230319(일) (3) | 2023.03.19 |
TIL 230318(토) 제네릭스, 타입 변수 (4) | 2023.03.18 |
댓글