람다표현식이란?
자바 8에서 추가된 람다표현식에 대해 알아봅시다. 람다표현식(Lambda expression)은 간단히 말해 메소드를 하나의 식(expression)으로 표현한 것으로 메서드의 이름과 반환값이 없어지므로 익명함수(anonymous function) 라고도 부릅니다.
자바에서는 자바 8 버전부터 람다식을 사용하여 함수형 프로그래밍을 할 수 있게 되었습니다.
//java7
int max(int a, int b){
return a > b ? a : b;
}
//java 8
(a, b) -> a > b ? a : b;
이러한 람다식은 메소드의 매개변수로 전달될 수도 있고, 메서드의 결과로 반환될 수도 있습니다.
따라서 람다식을 사용하면 기존의 불필요한 코드를 줄여 코드의 가독성을 높여줍니다.
람다 표현식 작성하기
람다식은 익명함수 답게 메서드에서 이름과 반환타입을 제거하고 매개변수의 선언부와 함수 몸체 사이에 '->' 를 추가하여 작성할 수 있습니다.
반환타입 메서드이름 ( 매개변수 ) {
code…
}
( 매개변수 ) -> {
code…
}
람다식을 사용할때 아래의 내용들을 유의하여야 합니다.
- 매개변수의 타입을 추론할 수 있는경우에는 타입을 생략할 수 있다.
(하나의 타입만 생략하는것은 불가능하다)( a , b ) -> a > b ? a : b //가능 (int a, b)-> a > b ? a : b //불가능
매개변수가 하나인 경우에는 소괄호(())를 생략할 수 있다.
(매개변수의 타입이 있으면 생략 불가능하다.)(a) -> a * a —————> a -> a * a //가능 (int a) -> a * a —————> int a -> a * a //불가능
함수의 몸체가 하나의 명령문만으로 이루어진 경우에는 중괄호({})를 생략할 수 있다.
(이때 세미콜론(;)은 붙이지 않아야 하며 중괄호 안의 문장이 return일 경우 중괄호를 생략할 수 없다)(String product, int count) -> { System.out.println(product+” = “+count); } (String product, int count) -> System.out.println(product+” = “+count) //가능
(int a, int b) -> { return a > b ? a : b;} // 가능
(int a, int b) -> return a > b ? a : b // 불가능
# 함수형 인터페이스
람다 표현식을 사용할때는 람다식을 사용하기 위한 참조변수에 저장해야 합니다.
타입 변수명 = 람다식
위에서 처럼 람다식을 하나의 변수에 대입할떄 사용하는 참조변수의 타입을 함수형 인터페이스라고 합니다.
이때 인터페이스에 @FunctionalInterface 애노테이션을 붙여 함수형 인터페이스임을 명시할 수 있습니다.
~~~java
@FunctionalInterface
interface Calculator { // 함수형 인터페이스 Calculator를 정의
public int max(int a, int b);
}
public class Lambda {
public static void main(String[] args){
Calculator maxNum = (a, b) -> a > b ? a : b; // 추상 메소드 구현
System.out.println(maxNum.min(3, 4)); // 함수형 인터페이스 사용
}
}
또 다른 예시로 기존에 Comparator인터페이스의 compare메소드를 오버라이드하여 복잡하게 구현하여 ArrayList를 정렬하였으나 람다식으로 간단하게 처리할 수 있다.
List<String> list =
Arrays.asList("abc", "cda", "abb", "bbb", "bdb", "ccc", "aaa");
//before
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});
//after
Collections.sort(list, (o1, o2) -> o2.compareTo(o1));
메서드 참조
메서드 참조는 람다식이 단하나의 메소드를 호출하는 경우에 람다식에서 불필요한 매개변수를 제거하고 사용할 수 있다.
//클래스이름::메소드이름
(base, exponent) -> Math.pow(base, exponent); //람다식
Math::pow; //메서드 참조
//참조변수이름::메소드이름
MyClass obj = new MyClass();
Function<String, Boolean> f = (x) -> obj.equals(x); //람다식
Function<String, Boolean> f = obj::equals); //메서드 참조
생성자 참조
생성자를 호출하는 람다식도 메서드 참조로 변환할 수 있다.
(a) ->{return new Object(a);}) //람다식
Object::new; //생성자 메서드 참조
배열을 생성할때도 생성자 참조를 사용할 수 있다.
Function<Integer, int[]> f = x-> new int[x]; //람다식
Function<Integer, int[]> f = int[]::new; //생성자 메서드 참조
메서드 참조는 람다식을 static변수처럼 다룰수 있게 해줘서 코드를 간략히 하는데 유용하다.
'프로그래밍 > Java' 카테고리의 다른 글
java8 - time (0) | 2020.03.10 |
---|---|
java8 - Optional (0) | 2020.02.23 |
java8 변경사항 - 스트림API 최종연산 (0) | 2020.02.07 |
Java8 변경사항 - 스트림API 중간연산 (0) | 2020.02.07 |
Java8 변경사항 - 스트림API 특징과 생성 (0) | 2020.02.01 |