@참고)
Java SE 8: Lambda Quick Start
Overview
- 람다 표현식은 single-method 클래스를 더 컴팩트하게 표현할 수 있도록 한다.
- 람다 표현식은 또한
Collection
으로 부터 데이터를 iterate, filter and extract 하는것을 쉽게 해준다.
- 추가로, 새로 추가된 동시성 관련 기능들은 멀티코어 환경에서의 퍼포먼스를 높여준다.
Background
- 익명 내부 클래스 Anonymous Inner Class
자바에서 익명 내부 클래스는 어플리케이션에 단 한번만 등장하는 클래스의 구현을 하는 방식을 제공합니다.
예를들어, Swing 혹은 JavaFX 애플리케이션에는 키보드 혹은 마우스 이벤트를 위한 다양한 이벤트 핸들러가 필요합니다. 각 이벤트 마다 필요한 분리된 이벤트 핸들링 클래스를 작성하기 보다 아래와 같은 방식으로 쓸 수 있습니다.
16 JButton testButton = new JButton("Test Button"); 17 testButton.addActionListener(new ActionListener(){ 18 @Override public void actionPerformed(ActionEvent ae){ 19 System.out.println("Click Detected by Anon Class"); 20 } 21 });
클래스를 따로 만드는것에 비하면 꽤 읽을만 한 코드 처럼 느껴집니다. 하지만 단 하나의 메서드를 정의하기 위해 꽤 많은 코드들이 추가 되었다는 점에서 코드가 엘레강스하지는 않습니다.
- 펑셔널 인터페이스 Functional Interfaces
ActionListener 인터페이스는 대충 아래 처럼 생겼습니다.
1 package java.awt.event; 2 import java.util.EventListener; 3 4 public interface ActionListener extends EventListener { 5 6 void actionPerformed(ActionEvent e); 7 8 }
ActionListener 는 하나의 추상 메서드(SAM, Single Abstract Method)를 가진 인터페이스의 예시입니다.
이런 인터페이스를
“functional interface”
라고 부릅니다.이런 패턴은 자바에서 꽤 흔합니다.
EventListener
인터페이스 외에 Runnalbe
, Comparator
같은 인터페이스들 역시 functional interface 입니다.- 람다 표현식 문법 Lambda Expression Syntax
람다 표현식은 익명 내부 클래스의 무지막지한 코드사이즈를 줄여줍니다.
내부 클래스의 메서드 하나 실행할떄 코드 5줄 쓰기 문제 (vertical problem)를 간단하게 바꾸어 줍니다.
람다 표현식은 세 파트로 구성됩니다.
Argument List | Arrow Token | Body |
(int x, int y) | → | x+y |
body는 하나의 표현식으로 구성될 수도 있고 statement block을 가질 수 도 있습니다.
- 하나의 표현식으로 구성된 body에서 body는 그냥 계산되고 return 됩니다.
- block으로 구성되어 있다면 메서드 바디 처럼 동작합니다. 즉, 직접 계산 로직을 구성하고 익명메서드의 caller 에게 return 하는 구문을 작성해야합니다.
- break,continue 키워드는 body의 탑 레벨에서는 사용할 수 없습니다. (내부 루프를 만든다면 사용가능)
(int x, int y) -> x + y () -> 42 (String s) -> { System.out.println(s); }
Argument List 의 변수 타입은 생략할 수 있습니다. - 컴파일러의 타입 추론
Lambda Expression Examples
20 // Lambda Runnable 21 Runnable r2 = () -> System.out.println("Hello world two!");
38 // Print Desc 39 System.out.println("=== Sorted Desc SurName ==="); 40 Collections.sort(personList, (p1, p2) -> p2.getSurName().compareTo(p1.getSurName()));