[Java] 람다식(Lambda Expressions)
1. 익명 클래스
자바에는 익명클래스를 통해서
재사용 되지도 않을 클래스가 계속 쌓이는것을 막을 수 있다.
대표적으로 쓰레드를 생성할때 아래와 같은 방법을 주로 사용한다.
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName() + " : hello world");
}
}
});
하지만 자바스크립트에 익숙한 사람이라면
위의 코드마저도 자바스크립트에서 콜백을 사용하는 방식과 비교해 보면
불필요한 코드가 굉장히 많다고 느껴질것이다.
2. 함수적 인터페이스
Runnable 인터페이스를 까보면 아래와 같다
@FunctionalInterface
public interface Runnable{
public abstract void run();
}
메서드가 오직 run밖에 없다
이렇게 구현할 메서드가 하나밖에 없는 인터페이스를 함수적 인터페이스라고 한다.
메소드가 여러개 있는 인터페이스를 구현할 때 메서드 몸체만 적어두면 그게 무슨 메서드를 구현한건지
모를텐데, 함수적 인터페이스 에서는 메서드 몸체만 있어도 되지 않을까?
따라서 함수적 인터페이스를 익명클래스로 만들때는
파라미터와 함수몸체만 적어주고싶은 생각이 들것같다.
3. 람다식
Thread의 생성자 중 하나는 Runnable을 파라미터로 받는다.
그렇다면 Thread 생성자에서 new Runnable을 적어주지 않아도
컴파일러가 추론할 수 있지 않을까?
이렇게 불필요한 코드는 줄이고자 하는 염원이 자바8에 반영되서
아래와 같은 람다 표현식으로 기존 익명클래스보다 더 간결하게 코딩하는것이 가능해졌다.
Thread t2 = new Thread(()->{
while(true){
System.out.println(Thread.currentThread().getName() + " : hello wolrd");
}
});
4. 표준 API에서 제공되는 함수적 인터페이스
종류 | 특징 | 설명 |
---|---|---|
Consumer | 매개값은 있고, 리턴값은 없음 | 매개값 -> Consumer |
Supplier | 매개값은 없고, 리턴값은 있음 | Supplier -> 리턴값 |
Function | 매개값도 있고, 리턴값도 있음 주로 매개값을 리턴값으로 매핑(타입 변환) | 매개값 -> Function -> 리턴값 |
Operator | 매개값도 있고, 리턴값도 있음 주로 매개값을 연산하고 결과를 리턴 | 매개값 -> Operator -> 리턴값 |
Predicate | 매개값은 있고, 리턴 타입은 boolean 매개값을 조사해서 true/false를 리턴 | 매개값 -> Predicate -> boolean |
람다식으로 작성되는 함수의 기능별로 인터페이스의 종류가 나눠진다.
각 종류별로 구체적인 인터페이스들이 많이 있다.
5. 람다식과 스트림
자바8에서 추가된 기능중 스트림은 람다식과 함께 자바 프로그래밍이 더욱더 간단해지게 만든다.
IntStream.range(1, 6)
.map(num -> num * num)
.forEach(num -> System.out.println(num));
각각의 스트림 처리 메서드들은 함수적 인터페이스를 파라미터로 받는다.
스트림 처리과정 중에서 세부적으로 어떻게 처리될지만 명시해 주면 자유자재로 스트림을 조작할 수 있다.