람다식이란?
람다식은 메서드를 하나의 식으로 표현 한것이며, 쉽게말해 이름이 존재하지 않아 익명함수라고 생각 할 수 있습니다.
간단한 메서드를 람다식으로 변환하는 예를 살펴보겠습니다.
람다식 사용하기
// 기존 메서드 작성 int sum(int a, int b){ return a + b; } // 람다 방식 (int a, int b) -> { return a + b; };
굉장히 간단하게 줄어들었습니다. 우선 기존 메서드 방식과의 차이점을 살펴보겠습니다.
익명함수처럼 사용되는 것이 바로 보입니다. 기존 메서드에서는 sum이라는 이름이 붙은 형태이지만 람다는 그렇지 않은 모습이죠.
람다를 사용하기 위해서는 다음과 같은 특징을 알아야 합니다.
- 매개변수가 하나라면 괄호 생략 가능
- 선언된 람다식의 매개변수 타입은 생략 가능
- 매개변수의 타입이 있으면 괄호 생략 불가능
- 반환 값이 있을땐, return을 생략하고 식으로 표현
- 람다의 내용이 문장 하나일땐 중괄호 생략 가능
위 특징을 이용해서 람다식을 더 줄여보겠습니다.
// 기존 메서드 작성 int sum(int a, int b){ return a + b; } // 람다 방식 (int a, int b) -> { return a + b; }; // 더 간단하게 (a, b) -> a + b;
적용된 특징을 한번 살펴보면
1. 매개변수 타입 생략
> int 형으로 선언 했었던 타입을 생략하였습니다.
2. return 생략
> 반환값을 나타내는 return 을 생략하였습니다.
3. 중괄호 생략
> 중괄호 안의 내용이 문장 하나로 구성되어있어서 생략 하였습니다.
위 세가지를 적용하여 아주 간단하게 표현 가능한 것을 볼 수 있습니다.
이번엔 모든 특징을 적용 한 형태를 보겠습니다.
// 기존 메서드 int square(int a){ return a * a; } // 람다 a -> a * a;
아주 간단하게 한줄로 표현 할 수 있습니다.
여기까지 보면 람다는 아주 쉽게 느껴질 수 있습니다. 하지만 막상 적용하려고 보면 이상하게 느껴지는 것이 한두가지가 아닙니다.
어떻게 매개변수 타입을 추론하지?
그래서 어떻게 사용하는 거지?
이 해답은 함수형 인터페이스에 나와있습니다.
람다식 사용하기 : 함수형 인터페이스
함수형 인터페이스란 추상 메서드가 단 하나만 선언되어있는 인터페이스를 말합니다.
// 함수형 인터페이스 interface SumInterface{ int sum(int a, int b); } // 추상 메서드 두개 : 함수형 인터페이스 X interface CalInterface{ int sum(int a, int b); int multiplication(int a, int b); }
람다는 위와같이 함수형 인터페이스가 있어야만 사용 가능합니다.
실제로 람다를 구현하기 위해서는 인터페이스를 변수화 해서 메서드를 담는 방법입니다.
// 함수형 인터페이스 interface SumInterface{ int sum(int a, int b); } public class Main{ public static void main(String[] args){ // 인터페이스를 변수에 선언한 뒤 람다를 이용하여 함수의 동작 할당 SumInterface lambdaTest = (a, b) -> a + b; // 할당한 함수 동작 lambdaTest.sum(10, 15); } }
위와같이 추상 메서드가 하나만 존재하는 함수형 인터페이스를 구현한 뒤, 변수를 이용해 할당하여 사용합니다.
실제로 람다를 이용해 sum 메서드의 동작을 명시했는데, 여기서 함수형 인터페이스만 가능한 이유를 유추할 수 있습니다.
람다는 어떤 메서드의 동작을 구현하는지 자기 자신은 모릅니다. 따라서 추상메서드가 하나만 존재하는 함수형 인터페이스만을 필요로 하는 것입니다. 메서드가 하나만 존재한다면 그 메서드만을 따라서 동작을 구현하면 되기 때문입니다.
10번째 줄에 함수의 동작을 구현하고 해당 동작은 바로 단 하나만 존재하는 추상 메서드인 sum의 동작으로 연결해주는 겁니다.
그래서 13번째 줄에서 람다의 동작은 sum 메서드를 호출해서 사용하고 있죠.
그럼 여기서 하나 더 알 수 있는 사실이 있습니다. 변수의 타입을 추론하는 방법은 바로 미리 선언된 함수형 인터페이스의 추상메서드의 변수 타입을 따라간다는 것입니다.
sum이라는 메서드는 받는 매개변수의 타입을 둘 다 int로 정의하고 있고 이에 따라서 람다식이 사용된 10번째 줄에서는 굳이 타입 언급 없이 매개변수만 넣어주어도 "아, 여기에 int가 들어올 것이구나." 라고 판단할 수 있는 것이죠.
이렇게 람다를 사용하는 방법과 매개변수 타입을 추론할 수 있는 이유를 함수형 인터페이스를 이용해서 알 수 있습니다.
그래서 왜 사용하는건데?
람다를 사용하는 이유
사실, 이 람다는 객체지향과는 반대되는 개념입니다. 이름에서도 알 수 있듯이 함수형 인터페이스를 사용하기 때문입니다.
객체지향적으로 프로젝트를 설계하다보면 한번만 쓰고 버려질 클래스가 부득이하게 생겨납니다. 따라서 해당 동작을 익명화 해서 일회성으로 사용하기 위해서 만들어진 것이 람다식입니다.
또한, 자주사용하는 함수형 인터페이스를 미리 정의해둔 패키지가 있습니다. (java.util.function)
람다는 보통 이 패키지를 이용하여 사용되기때문에, 제네릭에 대한 개념이 없으신 분들은 해당 개념을 같이 익히시면 좋을 것 같습니다.
제네릭이란?
2024.04.01 - [분류 전체보기] - [JAVA/자바] 제네릭(Generic)
함수형 인터페이스 | 추상 메서드 | 반환 타입 |
Supplier<T> | get() | T |
Consumer<T> | accept(T t) | void |
Function<T, R> | apply(T t) | R |
Predicate<T> | test(T t) | boolean |
사용 예시를 하나만 보겠습니다.
- Supplier
String text = "this is test"; // Supplier 인터페이스에 람다식 할당 Supplier<String> supplier = () -> text + " lambda"; // endText 변수에 get 추상메서드 동작 String endText = supplier.get(); // 결과값 : endText = "this is test lamda"
해당 내용들은 자바 스트림을 사용하면서 정말 많이 접하게 됩니다.
람다를 공부하시면서 스트림까지 같이 보시는 걸 추천드립니다.
스트림이란?
2024.03.25 - [개발/웹 개발] - [JAVA/자바] 스트림(Stream) 사용법
잘못된 내용이 있거나, 궁금하신 점은 댓글 남겨주세요.
'개발 > 웹 개발' 카테고리의 다른 글
[JAVA/자바] 옵셔널(Optional) (0) | 2024.08.30 |
---|---|
[JAVA/자바] 제네릭(Generic) (0) | 2024.04.01 |
[JAVA/자바]HttpURLConnection 이용한 파일 다운로드 (0) | 2023.02.08 |