java

람다식

주다애 2023. 7. 9. 17:15

🏹 람다식

프로그래밍 언어에서 사용되는 개념으로 '익명 함수'(이름이 없는 함수)를 지칭

자바에서는 Java 8부터 기능이 포함되었다.

(매개변수) -> {함수 구현}

위와 같이 화살표(->)를 이용해서 표현한다.

 

왜 쓰나?

람다식을 사용하는 이유는 몇 가지 있는데

1. 라인 수 감소

2. 함수의 의도가 명확하게 읽힘

3. 람다식으로 바로 실행문을 전달할 수 있음

4. 병렬 프로그래밍 가능

 

그런데 역시 좋기만 한 것은 아니다.

재사용이 불가하며 남발하게 되면 가독성이 떨어진다.

 

함수형 인터페이스

함수형 인터페이스가 갑자기 등장했는데 알아보니 추상 메서드를 한 개만 가지는 인터페이스를 뜻한다고 한다.

람다식이랑 무슨 연관이냐면 => 자바의 람다식은 함수형 인터페이스로만 사용이 가능하다.

@FunctionalInterface 어노테이션을 interface 위에 붙이면 된다.

@FunctionalInterface
interface Print {
    // 추상 메서드
    void printMethod(int a, int b);
}

class Test{
    public void testMethod(Print print) {
        print.printMethod(1, 2);
        System.out.println("실행");
    }
}

public class LambdaPracMain {
    public static void main(String[] args) {
        Test lambda = new Test();
        lambda.testMethod((a, b) -> {
            System.out.println(a + b);
            System.out.println(a * b);
        }); 
    }
}

Print 인터페이스가 함수형 인터페이스이다.(추상 메서드가 printMethod())

즉, 람다식으로 표현이 가능하다.

매개변수는 (a,b)이고 실행 함수는 {매개변수의 합과 곱을 출력}해주는 함수이다.

 

이렇게 직접 함수형 인터페이스를 만들어줘도 되고, 자바에서 지원해주는 함수도 있다.

// java에서 제공하는 FunctionalInterface function(람다식)
    public static void main(String[] args) {
        IntFunction intFunction = (a) -> a + 100;
        System.out.println(intFunction.apply(10));

        // 동일한 타입의 두 값을 받아서 연산 처리
        BinaryOperator binaryOperator = (a, b) -> a + " " + b;
        System.out.println(binaryOperator.apply("hi", "hello"));
    }

함수형 인터페이스의 함수를 호출할 때는 일반적으로 apply를 사용한다.(모든 함수형 인터페이스에 해당하는건 아니다.)

 

기억 저편에 apply를 썼던 함수가 있어서 찾아보니 BiFunction<>이 있었다.

BiFunction<String , String , Boolean> biFunction = (a, b) -> a.equals(b);
System.out.println(biFunction.apply("wow", "woww"));

매개변수로 String 타입을 2개 받으면 리턴 타입으로 Boolean을 반환해주는 함수이다.

여기서도 apply 함수를 사용했다.

(그냥 예시를 위한 함수이고 저렇게 사용하는게 좋은건지는 잘 모르겠다..)

 

no 람다식

람다식을 꼭 사용해야하는 것은 아닌 것 같다. (근데 자주 사용하는 것 같기도 하고 뭔가 문법이 멋있기도 하다.)

위의 printMethod()를 람다식을 사용하지 않고 구현하면

Test noLambda = new Test();
noLambda.testMethod(new Print() {
    @Override
    public void printMethod(int a, int b) {
        System.out.println(a + b);
        System.out.println(a * b);
    }
});

바로 읽었을 땐 좀 더 복잡한 것 같기도 하다.

 

근데 갑작스럽게도 여기서 의문이 생겼다. new Print()부분이다. 인터페이스를 new를 써도 되는가?

찾아보니,

익명 구현 객체(클래스를 작성하지 않고 객체를 생성하는 것)의 경우에는 참조할 구현 클래스가 없어서 new 뒤에 인터페이스 이름을 붙여도 된다고 한다.

대신, 익명 구현 객체의 구현부에는 인터페이스의 추상 메서드의 실체 메서드를 선언해야 한다고 한다.

인터페이스이름 변수 = new 인터페이스이름(
	추상 메서드를 구현한 메서드() {}
);

이렇게!

 

(사실 아직 어떤 문법을 써야할 지 잘 모르겠다. 일단 람다식을 알게된 것으로 끝!)

 

 

참고문헌

https://www.youtube.com/watch?v=3zd7HN-ZEUE&t=885s 

https://veneas.tistory.com/entry/Java-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EC%9D%B5%EB%AA%85-%EA%B5%AC%ED%98%84-%EA%B0%9D%EC%B2%B4

 

[Java] 인터페이스 익명 구현 객체

1. 익명 구현 객체 일반적으로 인터페이스에 대하여 구현 클래스를 만들어 사용하는 것이 재사용할 수 있기 때문에 편리합니다. 그러나 일회용으로 사용할 구현 객체를 위해서 소스 파일을 작성

veneas.tistory.com

 

'java' 카테고리의 다른 글

동일성 vs 동등성  (0) 2023.08.17
stream API + Optional  (0) 2023.07.15
stream API  (0) 2023.07.10
Optional  (0) 2023.07.09
상속  (0) 2023.07.08