Java8 in Action — 3장 #람다 표현식

Brant Hwang
QueryPie
Published in
5 min readJul 28, 2015
java_8_in_action

람다는 다음과 같은 특징을 가집니다.

  1. 익명 : 보통의 메서드와 달리 이름이 없으므로 익명이라 표현합니다. 구현해야 할 코드에 대한 걱정거리가 줄어듭니다.
  2. 함수 : 람다는 메서드처럼 특정 클래스에 종속되지 않으므로 함수라고 부릅니다. 하지만 메서드처럼 파라미터 리스트, 바디, 반환 형식, 가능한 예외 리스트를 포함합니다.
  3. 전달 : 람다 표현식을 메서드 인수로 전달하거나 변수로 저장할 수 없습니다.
  4. 간결성 : 익명 클래스처럼 많은 자질구레한 코드를 구현할 필요가 없습니다.

2장에서 봤던 코드를 다시 한번보겠습니다.

Comparator<Apple> byWeight = new Comparator<Apple>() {
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
}

기존의 익명클래스로 구현했던 방식에서 람다를 적용하면 다음과 같이 간결해집니다.

Comparator<Apple> byWeight = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());

람다는 크게 세부분으로 이루어져 있는데

  • 파라미터 리스트 : Comparator의 compare메서드의 파라미터(두 개의 사과) : (Apple a1, Apple a2)
  • 화살표 : 화살표 ( -> )는 람다의 파라미터 리스트와 바디를 구분합니다.
  • 람다의 바디 : 두 사과의 무게를 비교한다. 람다의 반환값에 해당하는 표현식입니다.

다양한 람다 예제

  • 불린 표현식 : (List<String> list) -> list.isEmpty()
  • 객체 생성 : () -> new Apple(10)
  • 객체에서 소비 : (Apple a) -> { System.out.println(a.getWeight()); }
  • 객체에서 선택/추출 : (String s) -> s.length()
  • 두 값을 조합 : (int a, int b) -> a * b
  • 두 객체 비교 : (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())

함수형 인터페이스

2장에서 사과를 분류하기 위해 Predicate<T>라는 인터페이스를 설계하고, 파라미터를 Predicate T 타입으로 확장할 수 있도록 코드를 구조화 했었습니다.

바로 Predicate<T> 같은 인터페이스가 함수형 인터페이스입니다. ‘이게 대체 무슨소리요?’

public interface Predicate<T> {
boolean test (T t);
}

쉽게 이야기하면 하나의 추상 메서드만 가지는 인터페이스가 함수형 인터페이스라 생각하면됩니다.

대표적으로 여러분들이 잘 알고 계시는 Ruunable, Comparator가 있습니다.

public interface Comparator<T> {
int compare(T o1, T o2);
}
public interface Runnable {
public void run();
}
보시다시피 Runnable, Comparator모두 유일한 추상 메서드를 가지는 인터페이스 들입니다.
정리하면, 함수형 인터페이스의 추상 메서드 구현체를 표현 하기위해 자바8 이전에는 익명클래스를 구현해야 했지만, 람다 표현식을 이용해서 간결하게 표현할 수 있다는 의미입니다.Runnable r1 = () -> System.out.println("Hello World");Runnable r2 = new Runnable() {
public void run() {
System.out.println("Hello World");
}
}
메서드 레퍼런스메서드 레퍼런스는 람다의 축약형입니다.// 익명 클래스 구현 방식
Comparator<Apple> byWeight = new Comparator<Apple>() {
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
}
// 람다 표현식
Comparator<Apple> byWeight = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
// 메서드 레퍼런스 & java.util.Comparator.comparing 활용
Comparator<Apple> byWeight = comparing(Apple::getWeight));
람다와 메서드 레퍼런스 단축 표현 예제
  • (Apple a) -> a.getWeight() = > Apple::getWeight())
  • () -> Thread.currentThread().dumpStack() => Thread.currentThread()::dumpStack
  • (str, i) -> str.substring(i) => String::substring
  • (String s) -> System.out.println(s) => System.out::println

--

--