본문 바로가기

공부내용 정리/자바

[JAVA] 람다(lambda) 표현식

 

람다 함수란?

람다함수는 프로그래밍 언어에서 사용되는 개념으로 익명함수(Anonymous functions)를 지칭하는 용어이다.

현재 사용되는 람다의 근간은 수학과 기초 컴퓨터과학 분야에서의 람다 대수이다.

람다 대수는 간단히 말하면 수학에서 사용하는 함수를 보다 단순하게 표현하는 방법이다.

 

람다의 특징

람다 대수는 이름을 가질 필요가 없다 -> 익명함수(Anonymous functions)

두개 이상의 입력이 있는 함수는 최종적으로 1개의 입력만 받는 람다 대수로 단순화될 수 있다. -> 커링(Curring)

 

익명함수?

익명함수란 말그대로 함수의 이름이 없는 함수이다. 익명함수들은 공통으로 일급객체(First Class citizen)라는 특징을 가지고 있다.

이 일급 객체란 일반적으로 다른 객체들에 적용 가능한 연산을 모두 지원하는 객체를 가르킨다.

함수를 값으로 사용할 수도 있으며 파라메터로 전달 및 변수에 대입하기와 같은 연산들이 가능하다.

 

람다의 장단점

장점

  1. 코드의 간결성 - 람다를 사용하면 불필요한 반복문의 삭제가 가능하며 복잡한 식을 단순하게 표현할 수 있다.
  2. 지연연산 수행 - 람다는 지연연산을 수행함으로써 불필요한 연산을 최소화할 수 있다.
  3. 병렬처리 가능 - 멀티쓰레드를 활용하여 병렬처리를 사용할 수 있다.

단점

  1. 람다식의 호출이 까다롭다.
  2. 람다 stream 사용시 단순 for문 혹은 while문 사용시 성능이 떨어진다.
  3. 불필요하게 너무 사용하게 되면 오히려 가독성이 떨어질 수 있다.

 

람다의 표현식

람다 표현식(lambda expression)이란?

간단히 말해 메소드를 하나의 식으로 표현한 것.

메소드

int min(int x, int y) {

return x < y ? x : y;

}

 

람다 표현식

(x, y) → x < y ? x : y;

 

위 처럼 메소드를 람다 표현식으로 표현하면, 클래스를 작성하고 객체를 생성하지 않아도 메소드를 사용할 수 있다.

자바에서는 클래스의 선언과 동시에 객체를 생성하므로, 단 하나의 객체만을 생성할 수 있는 클래스를 익명클래스라고 한다.

따라서 자바에서 람다표현식은 익명클래스와 같다고 할 수 있다.

람다 표현식

(x, y) → x < y ? x : y;

 

익명 클래스

new Object() {

int min(int x, int y) {

return x < y ? x : y;

}

}

이러한 람다 표현식은 메소드의 매개변수로 전달될 수 도 있으며, 메소드의 결괏값으로 반환될 수 도 있다.

기존의 불필요한 코드를 줄여주고, 작성된 코드의 가독성을 높여준다.

Java SE 8 부터는 이러한 람다 표현식을 사용하여 자바에서도 함수형 프로그래밍을 할 수 있게 되었다.

 

람다표현식 작성

자바에서는 화살표(->) 기호를 사용하여 람다 표현식을 작성할 수 있다.

문법

( 매개변수목록 ) -> { 함수몸체 }

유의사항

  1. 매개변수의 타입을 추론할 수 있는 경우에는 타입을 생략할 수 있다.
  2. 매개변수가 하나인 경우에는 괄호(())를 생략할 수 있다.
  3. 함수의 몸체가 하나의 명령문만으로 이루어진 경우에는 중괄호({})를 생략할 수 있다.(이때 세미콜론은 붙이지 않음)
  4. 함수의 몸체가 하나의 return 문으로만 이루어진 경우에는 중괄호({})를 생략할 수 없다.
  5. return문 대신 표현식을 사용할 수 있으며, 이때 반환값은 표현식의 결괏값이 된다.(이때 세미콜론은 붙이지 않음)

 

전통적인 방식의 스레드 생성과 람다 표현식을 사용한 스레드 생성을 비교하는 예제

→ 불필요한 코드를 줄이며, 코드 가독성이 좋아짐

new Thread(new Runnable() {

public void run() {

System.out.println(”전통적인 방식의 일회용 스레드 생성”);

}

}).start();

new Thread(()-> {

System.out.println(”람다 표현식을 사용한 일회용 스레드 생성”);

}

 

함수형 인터페이스(functional interface)

람다 표현식을 사용할 때는 람다 표현식을 저장하기 위한 참조 변수의 타입을 결정해야만 한다.

문법

참조변수의타입 참조변수의이름 = 람다 표현식

위의 문법처럼 람다 표현식을 하나의 변수에 대입할 때 사용하는 참조 변수의 타입을 함수형 인터페이스라고 부른다.

함수형 인터페이스는 추상 클래스와는 달리 단 하나의 추상 메소드만을 가져야 한다.

또한, 다음과 같은 어노테이션(annotation)을 사용하여 함수형 인터페이스임을 명시할 수 있다.

 

문법

@FunctionalInterface

위와 같은 어노테이션을 인터페이스의 선언 앞에 붙이면, 컴파일러는 해당 인터페이스를 함수형 인터페이스로 인식한다.

자바 컴파일러는 이렇게 명시된 함수형 인터페이스에 두 개 이상의 메소드가 선언되면 오류를 발생시킨다.

예제

@FunctionalInterface

interface Calc { // 함수형 인터페이스의 선언

public int min(int x, int y);

}

public class Lambda02 {

public static void main(String[] args) {

Calc minNum = (x, y) -> x < y ? x : y; // 추상 메소드의 구현

System.out.println(minNum.min(3, 4)); // 함수형 인터페이스의 사용

}

}