함수형 언어는 jdk 1.8부터 시작.
람다식 : 함수(메서드)를 간단한 식으로 표현하는 방법
int max(int a, int b){
return a > b ? a : b;
}
위와 같은 메소드를 아래처럼 간단한 식으로 만들어준다.
(a, b) -> a > b ? a: b
람다식은 익명함수이다.
람다식을 작성하는 방법
1. 메서드의 이름과 반환타입을 제거하고 →을 { }블록 앞에 추가한다.
(int a, int b) -> {return a > b ? a : b}
2. 반환값이 있는 경우, 식이나 값만 적고 Return문 생략가능(끝에 ';' 안붙임)
(int a, int b) -> a > b ? a : b
3. 매개변수의 타입이 추론가능하면 생략가능
(a, b) -> a > b ? a: b
람다식 작성 주의점
1. 매개변수가 하나인 경우, 괄호 생략가능(타입이 없을 때만)
a -> a * a //OK
int a -> a * a //ERROR
2. 블록 안의 문장이 하나일 때만, 괄호 생략이 가능하다.(끝에 ';' 안붙임)
(int i) ->{
System.out.println(i);
}
//아래와 같이 괄호 생략 가능. 세미콜론은 없어야한다.
(int i) -> System.out.println(i)
EX ) 문제를 람다식으로 표현하기
// 문제 1
int max(int a, int b){
return a > b ? a : b;
}
//정답
(a, b) -> a > b ? a : b
// ---------------------------------------------
//문제 2
int printVar(String name, int i){
System.out.println(name+"="+i);
}
//정답
(name, i) -> System.out.println(name+"="+i)
// ---------------------------------------------
// 문제 3
int square(int x){
return x * x;
}
//정답
x -> x * x
// ---------------------------------------------
// 문제 4
int roll(){
return (int)(Math.random()*6);
}
//정답
() -> (int)(Math.random()*6)
람다식은 익명함수가 아닌 익명 객체이다.
(a, b) -> a > b ? a : b
//위 람다식은 아래와 같다. (익명 클래스: 객체의 선언과 생성을 동시에 한다.)
new Object(){
int max(int a, int b){
return a > b ? a : b;
}
}
함수형 인터페이스
함수형 인터페이스 : 단 하나의 추상 메서드만 선언된 인터페이스
@FunctionalInterface
interface MyFunction{
public abstract int max(int a, int b);
}
함수형 인터페이스 MyFunction을 익명 클래스로 생성하기 :
MyFuction f = new MyFunction(){
public int max(int a, int b){
retuen a > b ? a : b;
}
};
위에서 보이다시피 함수형 인터페이스를 익명클래스로 생성할 수 있다.
즉 위의 MyFunction타입인 f의 메소드에 접근할 수 있다.(조상인 MyFunction 함수형 인터페이스에 메소드가 정의되어 있으므로)
int value = f.max(3, 5); //OK. MyFunction에 max()가 있음
함수형 인터페이스 타입의 참조변수로 람다식을 참조할 수 있다.
MyFunction f = (a, b) -> a > b ? a : b;
int value = f.max(3, 5); // 실제로는 람다식(익명 함수)이 호출됨
이처럼 함수형 인터페이스는 람다식을 참조로 사용하기 위해서 사용된다.
즉, 익명 객체인 람다식을 일반적인 객체의 메소드를 사용하는 것처럼 사용할 수 있게 해준다.
public class LambdaPractice {
public static void main(String[] args) {
// Object obj = (a, b) -> a > b ? a : 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;
int value = f.max(3, 5); /*함수형 인터페이스*/
System.out.println("value = "+value);
}
}
@FunctionalInterface//단 하나의 추상 메서드만 가져야 한다.
interface MyFunction{
public abstract int max(int a, int b);
}
위의 코드를 보면 Object타입으로 참조하여 람다식을 사용하려 했을 때는 Object에 max라는 메소드가 정의되어 있지 않기 때문에 사용할 수 없었지만, 함수형 인터페이스 MyFunction에 max를 정의하면 MyFunction타입으로 참조하여 사용할 수 있다.
Collection.sort :
Collections.sort에 익명 객체 대신 람다식을 사용할 수 있다.
public class Ex1401 {
public static void main(String[] args) {
List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "ada");
Collections.sort(list, new Comparator<String>(){//익명 객체
@Override
public int compare(String s1, String s2) {
return s2.compareTo(s1);
}
});
/* 익명 객체를 람다식으로 대체 */
List<String> list2 = Arrays.asList("abc", "aaa", "bbb", "ddd", "ada");
Collections.sort(list2, (s1, s2)->s2.compareTo(s1));//람다식
for (String s : list) System.out.print(s + " ");
System.out.println();
for (String s : list) System.out.print(s + " ");
}
}
실행결과:
ddd bbb ada abc aaa
ddd bbb ada abc aaa
함수형 인터페이스를 매개변수로 할 수도 있다.
@FunctionalInterface
interface MyFunction{
void myMethod();
}
public void aMethod (MyFunction f){
f.myMethod(); // MyFunction에 정의된 myMethod 메소드 호출
}
MyFunction f = () -> System.out.println("myMethod()");
aMethod(f);
aMethod(()-> System.out.println("myMethod()"));
함수형 인터페이스를 반환할 수도 있다.
MyFunction myMethod(){
Myfunction f = () -> {};
return f;
}
//위 코드와 아래 코드 모두 같다.
MyFunction myMethod(){
return () -> {};
}
출처: 남궁성님 유튜브 강의
https://www.youtube.com/user/MasterNKS
'java' 카테고리의 다른 글
Lambda 03 Predicate의 결합 (0) | 2021.12.26 |
---|---|
Lambda 02 - java.util.function 패키지 (0) | 2021.12.23 |
Serializable (0) | 2021.11.21 |
인터페이스 - 느슨한 결합력 (0) | 2021.04.25 |
자바의 다형성 (0) | 2021.03.25 |