본문 바로가기

언어공부/Java

자바 람다식(Lambda Expression, 익명함수), 함수형 인터페이스(Functional Interface), 메소드 참조

자바 람다식(Lambda Expression)에 대해서 알아보자.

람다식(Lambda Expression)

람다식은 간단히 말해서 메소드를 하나의 식으로 표현한 것이다. 람다식은 함수를 간략하면서도 명확하게 표현할 수 있게 해준다. 메소드를 람다식으로 표현하면 메소드의 이름과 반환값이 없어지므로, 람다식을 익명함수라고도 한다.

 

람다식은 오직 람다식 자체만으로 메소드의 역할을 대신할 수 있다. 

 

출력화면

 

람다식은 메소드의 매개변수로 전달되어지는 것이 가능하고, 메소드의 결과로 반환될 수도 있다. 람다식으로 인한 메소드를 변수처럼 다루는 것이 가능해진 것이다. 람다식에 선언된 매개변수의 타입은 추론이 가능한 경우는 생략할 수 있는데, 대부분의 경우에 생략이 가능하다. 람다식에 반환타입이 없는 이유도 항상 추론이 가능하기 때문이다.

 

선언된 매개변수가 하나뿐인 경우에는 괄호()를 생략할 수 있지만 매개변수의 타입이 있으면 괄호()를 생략할 수 없다.

 

마찬가지로 괄호{}안의 문장이 하나일 때는 괄호{}를 생략할 수 있다.(이 때 문장의 끝에 세미콜론(;)을 붙이지 않아야 한다. 그러나 괄호{}안의 문장이 return문일 경우 괄호{}를 생략할 수 없다.

 

자바에서 모든 메소드는 클래스 내에 포함되어야 하는데, 람다식은 익명클래스의 객체와 동등하다. 람다식으로 정의된 익명 객체의 메소드를 호출하려면 참조변수가 있어야한다. 해당 객체의 주소를 참조변수에 저장을 한다면 아래와 같다.

ex) 타입 f=(int a, int b) -> a>b? a: b; 

여기서 참조변수 f의 타입은 참조형이니깐 클래스 또는 인터페이스가 가능하다. 여기서 람다식과 동등한 메소드가 정의되어 있어야 하며, 참조변수로 익명 객체(람다식)의 메소드를 호출할 수 있다.

 

함수형 인터페이스(Functional Interface)

아래의 random 인터페이스에는 리턴타입이 int 인 추상메소드 method()가 정의되어 있다. 그리고 Test클래스에서 random인터페이스 타입 참조변수 f에 아래와 같이 익명객체 대신 람다식으로 대체해 대입할 수 있다. 왜냐하면 람다식도 실제로는 익명 객체이고, random인터페이스를 구현한 익명 객체의 메소드 method()와 람다식의 매개변수의 타입과 개수 그리고 반환값이 일치하기 때문이다. 이렇게 람다식을 다루기 위한 인터페이스를 "함수형 인터페이스(Functional Interface)"라고 한다.

 

 

출력화면

 


메소드 참조

메소드를 참조해 매개변수 타입, 개수 및 리턴타입을 알아내어 람다식에서 불필요한 매개변수를 제거한다. 메소드 참조도 람다식과 같이 인터페이스의 익명 객체로 생성된다. 

 

 

함수형 인터페이스인 Calculator는 리턴타입 int의 applyAsInt(int left, int left) 추상메소드가 있다. 여기에 람다식으로 객체를 생성할 수 있지만, 더 간단하게 메소드 참조로 객체를 생성할 수 있다.

 

메소드를 참조할 때, 정적메소드와 인스턴스메소드의 참조 방식은 다르며 아래와 같다.

 

  • 정적메소드 참조 >> 클래스 :: 메소드
  • 인스턴스 메소드 참조 >> 참조변수 :: 메소드

실행화면