[모던 자바 인 액션] 3장 - 람다 표현식

람다 표현식

람다 표현식이란 ?

람다 표현식은 메서드로 전달할 수 있는 익명 함수를 단순화한 것이라고 할 수 있다.

람다 표현식의 장점

람다 표현식을 활용하면 기존의 코드보다 훨씬 간결하고 유연하게 코드를 작성할 수 있게 된다.

익명 클래스로도 람다 표현식으로 구현한느 것들을 전부 다 구현할 수 있지만, 익명 클래스는 코드가 깔끔하지는 않다. 그래서 훨씬 깔끔한 코드로 동작을 구현하고 전달할 수 있는 람다 표현식을 사용하는 것이다.

람다의 기본 형태

  • (parameters) -> expression // expression : 표현식 (=식)
  • (parameters) -> { statements; } // statements : 제어문 (=문장, 구문)

람다 표현식 예시

  • (String s) -> s.length() : String 형식의 파라미터 하나르 ㄹ가지며, int를 반환한다. 람다 표현식에는 return이 함축되어 있으므로 return 문을 명시적으로 사용하지 않아도 된다.
  • (Apple a) -> a.getWeight() > 150 : Apple 형식의 파라미터 하나를 가지며 boolean(사과가 150그램보다 무거운지 결정)을 반환한다.
(int x, int y) -> {
    System.out.println("Result:");
    System.out.println(x + y);
} 
int 형식의 파라미터 2개를 가지며 리턴값이 없다(void 리턴). 람다 표현식은 여러 행의 문장을 포함할 수 있다. 
  • () -> 42 : 파라미터가 없으며 int 42를 반환한다.
  • () -> {} : 파라미터가 없으며 void를 반환하는 람다 표현식이다.
  • () -> "Raoul" : 파라미터가 없으며 문자열을 반환하는 표현식이다.
  • ~~(Integer i) -> return "Alan" + i;~~ : return은 흐름 제어문(statements)이다. 제어문을 사용하려면 반드시 중괄호({}}안에 제어문을 넣어야 한다. → (Integer i) -> { return "Alan" + i };
  • ~~(String s) -> { "Iron man";}~~ : "Iron man"은 문장(statements)가 아니라 표현식(expression)이다. → (String s) -> { return "Iron Man"; } 또는 (String s) → "Iron man"
  • () → { System.out.pinrtln("This is awesome"); } : 정상적인 람다식 활용 방법
  • [예외] () → System.out.println("This is awesome")) : 한 개의 void 메소드 호출은 중괄호로 감쌀 필요가 없다.

람다 표현식은 어디서 사용하는걸까?

람다 표현식은 ‘함수형 인터페이스’라는 문맥에서 사용할 수 있다.

함수형 인터페이스

함수형 인터페이스란 ?

하나의 추상 메서드만을 가지고 있는는 인터페이스가 ‘함수형 인터페이스‘이다.

예제 코드

public interface Adder {
    int add(int a, int b);
}

public interface SmartAdder extends Adder {
    int add(double a, double b);
}

public interface Nothing {
}
  • Adder는 하나의 추상 메서드만을 가지고 있으므로, 함수형 인터페이스이다.
  • SmartAdder는 두 추상 add() 메서드(하나는 Adder에서 상속받음)를 포함하므로 함수형 인터페이스가 아니다.
  • Nothing은 추상 메서드가 없으므로 함수형 인터페이스가 아니다.

‘함수형 인터페이스’와 ‘람다 표현식’의 관계

람다 표현식으로 함수형 인터페이스의 추상 메서드 구현을 직접 전달할 수 있다. 이 덕분에 익명 클래스보다 훨씬 간결하고 깔끔하게 코드를 작성할 수 있다.

예시 코드

public static void process(Runnable r) {
		r.run();
}

// 익명 클래스를 활용해서 process 메서드를 실행
process(new Runnable() {
    public void run() {
        System.out.println("Hello World 1");
    }
}); // 'Hello World 1' 출력

// 람다 표현식을 활용해서 process 메서드를 실행
process(() -> System.out.println("Hello World 2")); // 'Hello World 2' 출력