람다식이란?
JDK 1.8 부터 추가된 람다식(Lambda Expression)은 메서드를 하나의 식(Expression)으로 표현한것이다.
람다식은 함수를 간략하면서도 명확한 식으로 표현할 수 있다.
이러한 람다식은 메서드의 이름과 반환값을 제거할 수 있어 "익명함수" 라고도 한다.
람다식 형태
// 람다식 형태
(매개변수, ...) -> { 실행문 }
// 일반 메서드
public int sum(int a, int b){
return a + b;
}
// 일반 메서드를 람다식으로 변환
(int a, int b) -> { return a + b; };
위와 같이 람다식 형태는 익명함수처럼 메서드의 이름과 반환 타입을 제거하고 선언부와 몸통 사이에 -> 를 추가한다.
-> 가 있음으로써 왼쪽 매개변수를 이용해서 중괄호{} 를 실행한다는 뜻이다.
메서드의 중괄호 {} 안에서 return 문 1개만 존재할 경우 람다식에선 return 문과 중괄호를 생략할 수 있다.
(int a, int b) -> a + b
또한 람다식에 선언된 매개변수의 타입은 추론이 가능한 경우에 타입은 생략이 가능하다.
(a, b) -> a + b
주의점
(a) -> a + a
// 변환
a -> a + a
// 주의
(int a) -> a + a (OK)
int a -> a + a (NO)
위 내용처럼 매개변수가 하나뿐인 경우 괄호를 생략할 수 있다.
하지만 매개변수의 타입이 설정되어 있으면 괄호를 생략할 수 없다.
이중 콜론 연산자(메소드 참조 표현식)
이종 콜론(::) 연산자는 람다식을 사용할 때 중복되는 파라미터를 간결하게 표현할 수 있다.
사용방법은 [인스턴스]::[메소드명] 으로 사용한다.
List<String> names = Arrays.asList("홍길동", "이순신장군");
names.forEach(name -> System.out.println(name));
names.forEach(System.out::println);
// 결과
// names.forEach(name -> System.out.println(name));
> "홍길동"
> "이순신장군"
// names.forEach(System.out::println);
> "홍길동"
> "이순신장군"
"->" 키워드를 사용하여 람다식을 사용하는데 파라미터인 name 을 반복해서 사용한다면
"이중 콜론" 연산자를 사용하여 줄여서 사용할 수 있다.
위 내용중 "System.out" 은 인스턴스이고 "println" 은 인스턴스의 메소드명이다.
Stream Map() 을 이용해서 사용할 때
List<String> names = Arrays.asList("apple", "orange", "banana");
List<String> names2 = names.stream()
.map(name -> name.toUpperCase())
.toList();
List<String> names3 = names.stream()
.map(String::toUpperCase)
.toList();
System.out.println("names2 : "+names2.toString());
System.out.println("names3 : "+names3.toString());
// 결과
names2 : [APPLE, ORANGE, BANANA]
names3 : [APPLE, ORANGE, BANANA]
.map() 메서드는 Stream 의 요소들을 특정 요소로 변환하기 위해서 사용한다.
String toUpperCase 메서드를 활용하여 names 의 배열을 대문자로 변환하려고 한다.
람다식을 통해 사용한 문장인 "name -> name.toUpperCase()" 를
"String::toUpperCase" 로 변경하여 사용할 수 있다.
"String" 이 인스턴스이고 "toUpperCase" 가 String 인스턴스의 메서드이다.