자바 람다식(Lambda Expression)

웅평·2023년 12월 13일

람다식(Lambda Expression)이란?

  • 람다식(Lambda Expression)이란 함수를 하나의 식(expression)으로 표현한 것
  • 함수를 람다식으로 표현하면 메소드의 이름이 필요 없기 때문에, 람다식은 익명 함수(Anonymous Function)의 한 종류라고 볼 수 있다.
  • (전달값1(파라미터),전달값2...) -> (코드)

익명함수(Anonymous Function)란?

  • 함수의 이름이 없는 함수로, 익명함수들은 모두 일급 객체이다.

1급 객체(First-Class Object)

  • 변수나 데이터 구조 안에 담을 수 있다.
  • 파라미터로 전달 할 수 있다.
  • 반환값으로 사용할 수 있다.
  • 할당에 사용된 이름과 무관하게 고유한 구별이 가능하다.

    함수형 프로그래밍에서 함수는 1급 객체로 취급받기 때문에 위의 예제에서 본 것 처럼 함수를 파라미터로 넘기는 등의 작업이 가능한 것이다. 또한 우리가 일반적으로 알고 개발했던 함수들은 함수형 프로그래밍에서 정의하는 순수 함수들과는 다르다는 것을 인지해야 한다.

람다식(Lambda Expression) 의 특징

  • 람다식 내에서 사용되는 지역변수는 final이 붙지 않아도 상수로 간주된다.
  • 람다식으로 선언된 변수명은 다른 변수명과 중복될 수 없다.

람다식(Lambda Expression) 의 장점

  • 코드를 간결하게 만들 수 있다.
  • 식에 개발자의 의도가 명확히 드러나 가독성이 높아진다.
  • 함수를 만드는 과정없이 한번에 처리할 수 있어 생산성이 높아진다.
  • 병렬프로그래밍이 용이하다.

람다식(Lambda Expression) 의 단점

  • 람다를 사용하면서 만든 무명함수는 재사용이 불가능하다.
  • 디버깅이 어렵다.
  • 람다를 남발하면 비슷한 함수가 중복 생성되어 코드가 지저분해질 수 있다.
  • 재귀로 만들경우에 부적합하다.

선언방법

public void print() {
        String s = "test";
        System.out.println(s);
() -> {
        String s = "test";
        System.out.println(s);
  • 람다식은 접근제어자,이름, void 가 필요없다
public void print(String s) {
        System.out.println(s);
    }
s -> System.out.println(s);
  • 문장이 한줄이라면 {}생략, ;생략, String 생략가능 - 전달값이 컴파일러가 알수있기 때문이다
  • 전달값이 한개면 () 생략가능
public int add(int x, int y) {
        return x + y;
    }
(x, y) -> x + y
  • return이 있다면 {} 생략불가능

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

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

  • 일반적으로 '구현해야 할 추상 메소드가 하나만 정의된 인터페이스'를 가리킨다
  • 자바 컴파일러는 이렇게 명시된 함수형 인터페이스에 두 개 이상의 메소드가 선언되면 오류를 발생시킨다
//구현해야 할 메소드가 한개이므로 Functional Interface이다.
@FunctionalInterface
public interface Math {
    public int Calc(int first, int second);
}

//구현해야 할 메소드가 두개이므로 Functional Interface가 아니다. (오류 사항)
@FunctionalInterface
public interface Math {
    public int Calc(int first, int second);
    public int Calc2(int first, int second);
}

함수형 인터페이스 람다 사용예제
함수형 Interface 선언

@FunctionalInterface
interface Math {
    public int Calc(int first, int second);
}

추상 메소드 구현 및 함수형 인터페이스 사용

public static void main(String[] args){

   Math plusLambda = (first, second) -> first + second;
   System.out.println(plusLambda.Calc(4, 2));

   Math minusLambda = (first, second) -> first - second;
   System.out.println(minusLambda.Calc(4, 2));

}

람다식 연습

@FunctionalInterface
public interface Convertible {
    void convert(int USD);
}

public class KRWConverter implements Convertible {
    @Override
    public void convert(int USD) {
        System.out.println(USD + " 달러 = " + (USD * 1400) + "원");
    }
}
public interface Calculator{
	public int cal(int num1,int num2);
}

1) 매개변수가 없고, 리턴값이 없는 람다식

@FunctionalInterface
public interface ConvertibleWithNoParams {
    void convert();
}

public class _04_FunctionalInterface {
    public static void main(String[] args) {
        ConvertibleWithNoParams c1 = () -> System.out.println("1달러는 1400원");
        c1.convert();

    }
}

2) 매개변수가 있고, 리턴값이 없는 람다식

@FunctionalInterface
public interface ConvertibleWithTwoParams {
    void convert(int USD, int KRW);
}

public class _04_FunctionalInterface {
    public static void main(String[] args) {
        ConvertibleWithTwoParams c2 = (d, w) -> System.out.println(d + " 달러 = " + (d * w) + "원");

        c2.convert(10, 1500);

    }
}

3) 매개변수가 있고, 리턴값이 있는 람다식

@FunctionalInterface
public interface ConvertibleWithReturn {
    int convert(int USD, int KRW);
}


public class _04_FunctionalInterface {
    public static void main(String[] args) {
        ConvertibleWithReturn c3 = (d, w) -> {return d * w};
        int res = c3.convert(20, 1400);
        System.out.println(res + "원");
    }

    }
}

4) 매개변수가 없고, 리턴값이 있는 람다식

@FunctionalInterface
public interface JavaCoding {
    String nowCoding();
}

public class Execute {
    public static void main(String[] args) {
        //객체 선언
        JavaCoding jc;

        String str1 = "그 날을 잊지 못해 baby";
        String str2 = "날 보며 환히 웃던 너의 미소에";
        String str3 = "홀린 듯 I'm fall in love";

        jc = () -> {
            return str1;
        };
        System.out.println(jc.nowCoding());

        jc = () -> { return str2; };
        System.out.println(jc.nowCoding());

        //실행코드가 return 만 있는 경우 {}와 return문 생략가능
        jc = () -> str3;
        System.out.println(jc.nowCoding());
    }
}

참고
나도코딩 유튜브
https://mangkyu.tistory.com/113
https://khj93.tistory.com/entry/JAVA-%EB%9E%8C%EB%8B%A4%EC%8B%9DRambda%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EA%B3%A0-%EC%82%AC%EC%9A%A9%EB%B2%95

0개의 댓글