람다(Lambda)

박대운·2022년 11월 14일
0

Java

목록 보기
8/9

람다(Lambda)

람다식은 간단히 말해서 메서드를 하나의 ‘식(expression)’으로 표현한 것으로, 코드를 매우 간결하면서 명확하게 표현할 수 있다는 큰 장점이 있습니다.

람다식의 기본 문법

//기존 메서드 표현 방식
void sayhello() {
	System.out.println("HELLO!")
}

//위의 코드를 람다식으로 표현한 식
() -> System.out.println("HELLO!")

가장 먼저 두드러지는 차이는 람다식에서는 기본적으로 반환타입과 이름을 생략할 수 있다는 점입니다. 따라서 람다함수를 종종 이름이 없는 함수, 즉 익명 함수(anonymous function)라 부르기도 합니다.

int sum(int num1, int num2) {
	return num1 + num2;
}
(int num1, int num2) -> num1 + num2
(num1, num2) -> num1 + num2

기존 메서드를 람다식으로 표현한 함수. return 메서드에 세미콜론도 삭제할 수 있습니다.

// 기존 방식
void example3(String str) {
	System.out.println(str);
}

// 람다식
(String str) -> {	System.out.println(str);}

함수형 인터페이스

// sum 메서드 람다식
(num1, num2) -> num1 + num2

// 람다식을 객체로 표현
new Object() {
	int sum(int num1, int num2) {
		return num1 + num1;
	}
}

익명 클래스란 객체의 선언과 생성을 동시에 하여 오직 하나의 객체를 생성하고, 단 한번만 사용되는 일회용 클래스입니다.

객체의 생성과 선언을 한번에 할 수 있습니다.

만약에 람다식이 객체라 한다면 앞서 우리가 배웠던 것처럼 이 객체에 접근하고 사용하기 위한 참조변수가 필요합니다.

그런데 기존에 객체를 생성할 때 만들었던 Object 클래스에는 sum 라는 메서드가 없기 때문에, Object 타입의 참조변수에 담는다고 하더라도 sum 메서드를 사용할 수 없습니다.

public class LamdaExample1 {
    public static void main(String[] args) {
		   Object obj = new Object() {
            int sum(int num1, int num2) {
                return num1 + num1;
            }
        };
			// 람다식 Object obj = (num1, num2) -> num1 + num2 로 대체 가능
}

위의 코드 예제에서 익명 객체를 생성하여 참조변수 obj 에 담아준다 하더라도 sum 메서드를 사용할 수 있는 방법이 없습니다.

이 같은 문제를 해결하기 위해 사용하는 자바의 문법 요소가 바로 자바의 함수형 인터페이스(Functional Interface)라 할 수 있습니다.

public class LamdaExample1 {
    public static void main(String[] args) {
		   /* Object obj = new Object() {
            int sum(int num1, int num2) {
                return num1 + num1;
            }
        };
			*/ 
		ExampleFunction exampleFunction = (num1, num2) -> num1 + num2
		System.out.println(exampleFunction.sum(10,15))
}

@FunctionalInterface // 컴파일러가 인터페이스가 바르게 정의되었는 지 확인할 수 있도록
interface ExampleFunction {
		public abstract int sum(int num1, int num2);
}

// 출력값
25

함수형 인터페이스를 활용하여 자바의 문법 요소를 해치지 않으면서도 우리가 원하는 결과를 얻어낼 수 있습니다.

매개변수와 리턴값이 없는 람다식

@FunctionalInterface
public interface MyFunctionalInterface {
    public void accept();
}
MyFunctionalInterface example = () -> { ... };

// example.accept();

람다식이 대입된 인터페이스의 참조 변수는 위의 주석과 같이 accept()를 호출할 수 있습니다. accept()의 호출은 람다식의 중괄호 {} 를 실행시킵니다.

public class MyFunctionalInterfaceExample {
	public static void main(String[] args) throws Exception {
		MyFunctionalInterface example;
		example = () -> {
			String str = "첫 번째 메서드 호출!";
			System.out.println(str);
		};
		example.accept();

		example = () -> System.out.println("두 번째 메서드 호출!");
		//실행문이 하나라면 중괄호 { }는 생략 가능
		example.accept();
	}
}

// 출력값
첫 번째 메서드 호출!
두 번째 메서드 호출!

매개변수가 있는 람다식

@FunctionalInterface
public interface MyFunctionalInterface {
    public void accept(int x);
}
public class MyFunctionalInterfaceExample {
    public static void main(String[] args) throws Exception {
        MyFunctionalInterface example;
        example = (x) -> {
            int result = x * 5;
            System.out.println(result);
        };
        example.accept(2);

        example = (x) -> System.out.println(x * 5);
        example.accept(2);
    }
}

// 출력값
10
10

람다식이 대입된 인터페이스 참조 변수는 다음과 같이 accept()를 호출할 수 있습니다. 위의 예시와 같이 매개값으로 2를 주면 람다식의 x 변수에 2가 대입되고, x는 중괄호 { }에서 사용됩니다.

리턴값이 있는 람다식

@FunctionalInterface
public interface MyFunctionalInterface {
    public int accept(int x, int y);
}
public class MyFunctionalInterfaceExample {
    public static void main(String[] args) throws Exception {
        MyFunctionalInterface example;
        example = (x, y) -> {
            int result = x + y;
            return result;
        };
        int result1 = example.accept(2, 5);
        System.out.println(result1);
        

        example = (x, y) -> { return x + y; };
        int result2 = example.accept(2, 5);
        System.out.println(result2);
       

	      example = (x, y) ->  x + y;
				// 실행문이 한 줄인 경우, 중괄호 {}와 return문 생략가능
        int result3 = example.accept(2, 5);
        System.out.println(result3);
       

        example = (x, y) -> sum(x, y);
				// 실행문이 한 줄인 경우, 중괄호 {}와 return문 생략가능
        int result4 = example.accept(2, 5);
        System.out.println(result4);
 
    }

    public static int sum(int x, int y){
        return x + y;
    }
}

//출력값
7
7
7
7
profile
성장하는사람이 되자

0개의 댓글