Java

[Java] 람다식?

lala9663 2022. 10. 18. 01:51

람다식(Lambda Expressions)

메서드를 하나의 식으로 표현한 것!
이름 없는 메서드!

그래서 람다식이란??

  • 람다식이란 함수명을 선언하고 사용하는 것이 아닌 식별자 없이 실행가능한 함수이다.
  • 절차형 프로그래밍, 객체지향 프로그래밍과는 사뭇 다르게 함수의 구현과 호출만으로 프로그램을 만드는 방식인 함수형 프로그래밍에서 자주 사용된다.
  • 자바 8부터 도입되었으며, 람다식을 익명함수를 만드는 것인데 익명함수는 일급객체 특징을 가지고 있다.
  • 람다식 사용법은 (매개변수,...) -> {실행문...} 다음과 같이 사용하면 된다.

메서드를 람다식으로 표현하면 메서드 이름과 반환값이 없어지므로 익명 함수(annonymous function) 라고도 부른다.
특히 메서드가 1번만 사용되고 메서드의 길이가 짧은 경우 매우 유용하다.

자바에서 메서드(함수) 혼자서 생존할 수 없다. 객체가 아니기 대문에 클래스도 만들어야 하고, 객체도 생성해야 쓸 수 있다. 하지만 람다식으로 인해 변수처럼 스스로 존재하며 매개변수로 전달하거나 결과로 반환될 수 있다.

일급객체란?

함수형 프로그래밍에 1급객체라는 말을 자주 사용한다. Java와 Kotlin의 비교를 통해 Kotlin함수는 1급 객체지만, Java는 1급객체가 아니라는 것을 알 수 있다.

  1. 함수를 변수에 할당할 수 있어야 한다.
  2. 다른 함수의 파라미터로 함수 객체를 넘길 수 있어야 한다.
  3. 함수의 리턴값으로 함수 객체를 리턴할 수 있어야 한다.

이 3가지 조건을 만족하면 1급객체라고 할 수 있다.

람다식으로 작성하기

 

 

반환값이 있는 메서드의 경우 return 문 대신 '식(expression)' 으로 대신 할 수 있다.
식의 연산결과가 자동적으로 반환값 이 되기 때문이다.
이 때는 문장이 아니고 식(expression)이므로 끝에 세미콜론; 을 붙이지 않는다.
그리고 몸통 {} 안의 문장이 하나일 때는 생략 할 수 있다.
만약 return 문으로 계속 쓸 경우 몸통 {} 을 생략할 수 없다.

 

 

매개변수의 타입은 추론 가능한 경우는 생략하는데 대부분의 경우는 생략이 가능하다.
람다식에 반환타입이 없는 이유도 항상 추론이 가능하기 때문이다.

 

 

람다식은 0개 이상의 매개 변수를 가질 수 있다.
0개일 경우 () -> {} 괄호를 써서 적는다.
그리고 매개변수가 1개일 때는 괄호를 생략할 수 있다.

 

 

예시

interface OperatorInterface{
    int oper(int a, int b);
}

public class Hello {
    public static void main(String[] args) {

        OperatorInterface operatorInterface = new OperatorInterface() {
            @Override
            public int oper(int a, int b) {
                return a+b;
            }
        };
        System.out.println(operatorInterface.oper(20,10));      // 30

        OperatorInterface operatorInterface1 = ((a, b) -> {
           return a-b;
        });
        System.out.println(operatorInterface1.oper(20,10));     // 10
    }
}

람다식은 익명 객체이다.

위에서 봤듯이 Java에서 모든 메서드는 클래스에 포함되어 있어야했다.
하지만 람다식으로 쓴다면 클래스를 쓰지 않아도 가능하며, 객체로 취급한다고 했다.
그렇다면 람다식은 어떤 클래스에 포함되는 것인가?
람다식은 익명 클래스의 객체와 동등하다.

 

익명클래스란?

클래스 선언과 객체의 생성을 동시에 하여 한번만 사용될 수 있고 오직 하나의 객체만 생성할 수 있는 일회용 클래스

 

그렇다면 람다식으로 정의된 익명객체의 메서드를 어떻게 호출할까?

참조 변수가 있어야 객체의 메서드를 호출할 수 있다.
그러므로 위 익명 객체에 참조변수 f를 넣어보자.

타입 f = (int x, int y) -> x +y;

이 때 참조변수 f의 타입은 클래스 또는 인터페이스가 가능하다.
그리고 람다식과 동등한 메서드가 정의되어 있는 것이어야 한다.
그래야 참조변수로 익명 객체(람다식)의 메서드를 호출할 수 있기 때문이다.

이 익명 객체를 다룰 수 있는 인터페이스가 필요한데 Object 타입으로 하기에는 람다 기능을 Object 클래스에 넣어야하는 부담이 생긴다. 그래서 람다식을 저장할 수 있는 참조변수는 '함수형 인터페이스' 타입 이어야 한다.

함수형 인터페이스(Functional Interface)란 무엇인가?

이것은 하나의 추상 메서드만을 갖는 인터페이스 이다.
그래야지 람다식과 인터페이스의 메서드가 1:1로 연결될 수 있기 때문이다.
이 추상 메서드의 매개변수의 개수와 타입, 리턴타입과 동일한 람다식을 할당해서 사용할 수 있다.
(함수형 인터페이스의 Statice 메서드와 Default 메서드의 개수에는 제약이 없다.)

 

참조

https://ssdragon.tistory.com/m/14