[0824-25] 자바 람다식(람다식, 함수형 인터페이스)
#람다식
- 함수형 프로그래밍 기법을 지원하는 자바의 문법요소.
- 메서드를 하나의 '식'으로 표현한 것.
- 코드를 간결하고 명확하게 표현할 수 있다.
- 객체지향 프로그래밍과 함수형 프로그래밍을 혼합하는 방식으로 더 효율적 프로그래밍 가능.
- 람다식과 기존 메서드의 비교
// 기존 메서드
void sayhi() {
System.out.println("HI");
}
// 람다식
() -> System.out.println("HI");
- 람다식은 반환타입과 이름을 생략할 수 있어, 익명 함수(anonymous function)이라고도 부른다.
- 람다식 예시 코드
int sum(int num1, int num2) {
return num1 + num2;
}
(int num1, int num2) -> { // 반환타입과 메서드명 삭제 + 화살표 추가
return num1 + num2;
}
// 기존 방식
void example3(String str) {
System.out.println(str);
}
// 람다식
(String str) -> { System.out.println(str);}
- 특정 조건 총족시 람다식의 더욱 축약할 수 있다.
// 기존 방식
int sum(int num1, int num2) {
return num1 + num2;
}
// 람다식
(int num1, int num2) -> {
num1 + num2
}
// 메서드 바디에 실행문이 하나만 존재할 때, 중괄호와 return문을 생략 가능
(int num1, int num2) -> num1 + num2 // 세미콜론도 생략된다.
// 매개변수 타입을 함수형 인터페이스를 통해 유추할 수 있는 경우 매개변수 타입을 생략 가능
(num1, num2) -> num1 + num2
# 함수형 인터페이스
- 기존의 인터페이스 문법을 활용하여 람다식을 다루는 것
- 람다식 또한 객체이기 때문에 클래스를 통해 만들어야 한다.
- 람다식은 이름이 없는 익명객체이기 때문에 익명 클래스를 통해 만들어진다.
- 익명 클래스는 객체의 선언과 생성을 동시에 하여 오직 하나의 객체를 생성하고, 단 한 번만 사용되는 일회용 클래스이다.
- 이 때 익명 클래스의 특징으로 인해, 선언한 람다식 메서드를 외부에서 사용하지 못하는 문제가 생긴다.
이를 해결하기 위해 자바의 함수형 인터페이스 문법을 활용하여 람다식을 다룬다.
- 함수형 인터페이스의 특징은 단 하나의 추상 메서드만 선언될 수 있다.
- 익명 클래스로 쓰여진 람다식과 함수형 인터페이스로 쓰여진 람다식의 비교
public class LamdaExample1 { // 익명클래스 활용
public static void main(String[] args) {
Object obj = (num1, num2) -> num1 + num2;
obj.sum(5, 7);
}
}
/* 출력결과
error: cannot find symbol
obj.sum(5, 7);
^
symbol: method sum(int,int)
location: variable obj of type Object
*/
public class LamdaExample2 { // 함수형 인터페이스 활용
public static void main(String[] args) {
ExampleFunction exampleFunction = (num1, num2) -> num1 + num2;
System.out.println(exampleFunction.sum(5,15));
}
@FunctionalInterface // 컴파일러가 인터페이스가 바르게 정의되었는지 확인하는 어노테이션
interface ExampleFunction {
int sum(int num1, int num2);
}
// 출력값
20
#매개변수와 리턴값이 없는 람다식의 함수형 인터페이스 활용
- 매개변수를 가지지 않는 메서드를 가진 함수형 인터페이스를 람다식으로 작성할 때 다음과 같이 작성할 수 있다.
@FunctionalInterface
interface MyfunctionalInterface {
void accept();
}
public class MyFunctionalInterfaceExample {
public static void main(String[] args) throws Exception {
MyFuntionalInterface example = () -> System.out.println("accept()가 호출됩니다");
example.accept();
}
}
// 출력값
accept()가 호출됩니다
#매개변수가 있는 람다식의 함수형 인터페이스 활용
- 매개 변수는 있고 리턴값이 없는 메서드를 가진 함수형 인터페이스를 람다식을 작성할 때 다음과 같이 작성할 수 있다.
public class MyFunctionalInterfaceExample {
public static void main(String[] args) throws Exception {
MyFunctionalInterface example;
example = (x) -> {
int result = x * 10;
System.out.println(result);
};
exampel.accept(5);
example = (x) -> System.out.println(x * 10);
example.accept(5);
}
}
// 출력값
50
50
#리턴값이 있는 람다식의 함수형 인터페이스 활용
- 매개 변수와 리턴값을 가지는 추상 메서드를 포함하는 함수형 인터페이스를 람다식으로 작성할 때 다음과 같이 작성할 수 있다.
public class MyFunctionalInterfaceExample {
public static void main(String[] args) throws Exception {
MyFunctionalInterface example;
example = (x, y) -> {
int result = x - y;
return result;
};
int result1 = example.accept(10, 5);
System.out.println(result1);
example = (x, y) -> { return x - y; };
int result2 = example.accept(10, 5);
System.out.println(result2);
example = (x, y) -> x - y;
//return문만 있으면, 중괄호 {}와 return문 생략 가능
int result3 = example.accept(10, 5);
System.out.println(result3);
example = (x, y) -> sum(x, y);
//return문만 있으면, 중괄호 {}와 return문 생략 가능
int result4 = example.accept(5, 5);
System.out.println(result4);
}
public static int sum(int x, int y){
return x + y;
}
}
//출력값
5
5
5
10