일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Spring
- @Header
- 쓰레드 라이브러리
- OS
- functional interface
- FunctionalInterface
- SystemCall
- Process
- 롬복주의점
- Thread Library
- ReflectUtils
- 프로세스
- 함수형 인터페이스
- rainbow table
- django-crontab
- Thread Multiplexing
- 운영체제
- sql-mappler
- none이미지
- 문자열 불변성
- python-socketio
- 도커
- AOP
- custom annotation
- task_struct
- hiberbate
- 문자열 리터럴
- java.util.function
- spring-data-jpa
- strict stubbing
- Today
- Total
JH's Develog
[JAVA] 람다식 Lambda Expression 본문
JDK1.8 부터 추가된 람다식은 자바를 객체지향언어인 동시에 함수형 언어가 될 수 있게 해주었습니다. 람다식 덕분에 자바는 기존의 자바를 거의 변경하지 않고도 함수형 언어의 장점을 잘 접목시키는데 성공할 수 있었습니다.
람다식을 한마디로 표현하자면 "메서드를 하나의 식으로 표현한 것"입니다.
int[] arr = new int[5];
Arrays.setAll(arr, (i) -> (int)(Math.random()*5+1) );
위 코드에서 (i) -> (int)(Math.random()*5+1) 부분이 바로 람다식인데, 이렇게 람다식을 활용하면 람다식 자체만으로도 메서드의 역할을 대신할 수 있습니다. 게다가 람다식은 메서드의 매개변수로 전달되거나 결과값으로 반환될 수도 있으므로 람다식으로 인해 메서드를 변수처럼 다루는 것이 가능해집니다.
람다식의 작성규칙
1. 메서드에서 이름과 반환타입을 제거하고 선언부와 몸통사이를 '->'로 연결한다.
//원래 형태
int max(int a, int b){
return a > b ? a : b;
}
// 변환된 형태
(int a, int b) -> { return a > b ? a : b;}
2. return 값이 있는 메서드의 경우 return문을 식으로 대신할 수 있다. 이때에는 문장 끝에 세미콜론(;)을 붙이지 않는다.
//변환 전
(int a, int b) -> { return a > b ? a : b; }
//변환 후
(int a, int b) -> a > b ? a : b
3. 매개변수의 타입은 추론이 가능한 경우 생략가능하다. (대부분의 경우 생략가능)
//변환 전
(int a, int b) -> a > b ? a : b
//변환 후
(a, b) -> a > b ? a : b
단 "(int a, b) -> a>b?a:b" 와 같이 둘 중 어느 한쪽만 생략하는 것은 허용되지 않습니다.
4. 선언된 매개변수가 하나라면 괄호()를 생략할 수 있다. (단, 타입이 있으면 안된다.)
//변환 전
(int a) -> a + a
//변환 후
a -> a + a
//에러 발생
int a -> a + a
5. 중괄호 {} 안의 문장이 한 줄일 때는 중괄호{}를 생략할 수 있다. (단 return문일 경우는 제외)
//변환 전
(name, age) -> {System.out.println(name + " " +age);}
//변환 후
(name, age) -> System.out.println(name + " " +age)
//에러 발생
(a, b) -> return a > b ? a : b
함수형 인터페이스
자바에서 모든 메서드는 클래스 내에 포함되어야 하는데 람다식은 어디에 포함되어 있을까요?
지금까지 람다식을 메서드 처럼 취급했지만 사실 람다식은 익명 클래스(anonymous class)와 동일하다고 볼 수 있습니다.
예를들어 다음과 같은 인터페이스가 정의되어 있다고 가정했을 때,
interface MyFunction{
public abstract int max(int a, int b);
}
//위 인터페이스의 객체를 생성해서 메서드를 사용해보면
MyFunction f = new Myfunction(){
public int max(int a, int b){
return a > b ? a : b;
}
}
int maxValue = f.max(5, 3);
람다식은 실제로 익명 객체이기 때문에, 다음과 같이 간단하게 익명 객체를 람다식으로 대체할 수 있습니다.
MyFunction f = (a, b) -> a > b ? a : b;
f.max(5,3);
이렇게 람다식은 인터페이스를 통해 다루며, 람다식을 다루기 위한 인터페이스를 "함수형 인터페이스(Functional interface)"라고 합니다.
람다식과 인터페이스의 메서드가 1대1로 연결되기 때문에, 함수형 인터페이스에는 오직 하나의 추상 메서드만 정의되어 있어야합니다.
즉 위에서 정의한 MyFunction은 함수형 인터페이스 입니다.
@FunctionalInterface
interface MyFunction{
public abstract int max(int a, int b);
}
함수형 인터페이스를 정의할 때 @FunctionalInterface 어노테이션을 붙여준다면 컴파일러가 함수형 인터페이스를 올바르게 정의하였는지 확인해주므로, 반드시 붙이는 편이 좋습니다.
람다식을 참조변수로 다룰 수 있다는 것이 바로 변수처럼 메서드를 주고받는 것을 가능하게 하는 점입니다.
다음과 같이 매개변수나 반환형이 함수형 인터페이스라면, 다음과 같이 람다식의 참조변수를 반환하거나 매개변수로 람다식을 받을 수 있습니다.
// 매개변수의 타입이 함수형 인터페이스라면?
void method1(MyFunction f){
f.myMethod();
}
method1( (a, b)-> a > b ? a : b );
// 반환형의 타입이 함수형 인터페이스라면?
MyFunction method2(){
MyFunction f = (a, b) -> a > b ? a : b;
return f;
}
이렇게 람다식을 사용하면 코드를 간결하고 이해하기 쉽게 작성할 수 있습니다.
'JAVA' 카테고리의 다른 글
[JAVA] 자바 쓰레드 동기화(2) - ReentrantLock과 Condition (0) | 2022.07.06 |
---|---|
[JAVA] Object level lock vs Class level lock (0) | 2022.07.05 |
[JAVA] 자바 쓰레드 동기화(1) - synchronized, wait()/notify() (0) | 2022.07.05 |
[JAVA] 문자열 리터럴이 불변인 이유 (Why String is immutable?) (0) | 2022.01.14 |
[JAVA] 함수형 인터페이스 (Functional Interface) (0) | 2022.01.03 |