[JAVA] Lambda 썬더

Kevin·2024년 5월 4일
8

JAVA

목록 보기
11/16
post-thumbnail

🤨 서론

“람다” 너무나 많이 들어보았던 기능이다.

그러나 누군가 나에게

“람다”가 뭐야?

“람다”를 사용하는 목적이 뭔데?

“맞을래요?”

라고 묻는다면 제대로 답변을 할 수 없을 것이다.

매번 그렇지만 언젠가 제대로 공부해야지 해야지 하다 매번 미뤄지는 것들이 많은 것 같다.


@RequestMapping(value = "/ex.do", method = RequestMethod.POST)
	public void selectExcel(@RequestParam(value = "arr[]") List<String> arr,
			HttpServletRequest request, HttpServletResponse response, ModelMap model) {

		ExecutorService executor = Executors.newFixedThreadPool(arr.size());

		for (String target : arr) {
			executor.execute(() -> {
					// Lambda
			});
		}

		executor.shutdown();
	}

그중에 람다는 위 코드에서의 executor.execute(() -> {}); 처럼 스스로도 이미 많이 사용하고 있었던 기능이다.

반성을 글 서두로 시작하며 람다에 대해서 이야기 해보고자 한다.

😳 본론

1. 람다식 이해하기

람다를 이해하기 위해서는 먼저 함수형 프로그래밍이란 무엇인지에 대해서 이해하고 넘어가면 좋을 것 같다.

우리가 사용하는 자바는 모두 잘 알다시피 객체 지향 프로그래밍이다.

객체 지향 프로그래밍은 기능을 수행하기 위해서 객체를 만들고, 그 객체 내부에 멤버 변수를 선언하고 기능을 수행하는 메서드를 구현해야 한다.

다른 의미로 함수형 프로그래밍은 함수의 구현과 호출 만으로 프로그래밍이 수행되는 방식을 의미한다.

이 때 함수는 외부의 변수를 사용하지 않고, 오직 인자로 넘겨받은 매개변수를 사용해야 한다는 점이 특이점이다.

그 이유는 외부 자료에 부수적인 영향(side effect)를 주지 않도록 하기 위함이다.

이러한 특징으로 인해 여러 자료가 동시성 걱정 없이 병렬 처리가 가능하다.

자바는 8 version 부터 함수형 프로그래밍 방식을 지원하는데, 이를 람다식이라고 한다.

# ex Python

def print_hello() {
	print("hello")
}
// ex JAVA
public class Hello

	public void printHello() {
		System.out.println("hello");
	}

그러나 자바는 자바스크립트와 파이썬과 같이 함수만 따로 구현할 수 없다.

그렇기에 자바는 인터페이스를 만들고 이를 람다식으로 구현하는 방식을 방법으로 사용한다.

  1. 인터페이스 생성

    public interface Add{
    
    	public int add(int x, int y);	
    
    }
  2. 인터페이스에 선언한 메서드를 람다로 구현 및 사용

    // 구현
    Add add = (x, y) -> (return x+y;)};
    
    // 사용
    add.add(2,3);

원래 자바에서는 인터페이스에서 메서드를 선언하고, 해당 인터페이스를 구현한 구현 클래스에서 메서드를 구현해야하는데 람다를 사용하면 구현체를 만들지 않고, 함수를 구현 및 사용할 수 있다.

그러나 사실 내부적으로 자바에서는 객체(구현체) 없이 메서드가 호출 될 수는 없기에, 람다식을 구현하면 익명 내부 클래스가 만들어지고 이를 통해 익명 객체가 생성된다.


그렇기에 익명 내부 클래스에서와 마찬가지로 람다식 내부에서도 외부에 있는 지역 변수의 값을 변경하면 오류가 발생한다.


2. 람다식 문법

위에서는 자바의 람다식에 대해서 이야기를 했었고, 이제 본격적으로 자바에서 람다식을 어떻게 다루는지에 대해서 이야기를 해보자.

람다식은 아래와 같은 기본 문법을 지닌다.

(매개변수) -> {실행문;}

이를 예시를 들며 같이 알아보자.


두 수를 입력 받아 더하는 add() 함수가 아래와 같이 있다.

int add(int x, int y){

    return x+y;
}

위의 add()를 람다식으로 표현한다면 다음과 같다.

(int x, int y) -> {return x+y;}

람다식 문법에는 매개 변수의 개수나 실행문에 따라 괄호를 생략 가능한 경우가 있다.


매개 변수가 하나인 경우 자료형과 괄호 생략가능하다.

str->{System.out.println(str);}

매개변수가 두 개 이상인 경우 괄호를 생략할 수 없다.

x, y -> {System.out.println(x+y);}  //오류

만약 실행문이 한 문장인 경우에는 중괄호를 생략 가능하다.

str-> System.out.println(str);

실행문이 한 문장이라도 return문(반환문)은 중괄호를 생략할 수 없다.

str-> return str.length();  //오류

실행문이 한 문장의 반환문인 경우엔 return과 중괄호를 모두 생략 가능하다.

(x, y) -> x+y;
str -> str.length;


3. 함수형 인터페이스

@FunctionalInterface
public interface MyNumber {
	
	int getMax(int num1, int num2);

}

함수형 인터페이스는 위에서 잠깐 이야기 했었지만 람다식을 선언하기 위한 인터페이스이다.

람다식은 익명 함수와 매개 변수만으로 구현되기에, 만약 함수형 인터페이스 내에 메서드가 여러개 있다면 어떤 메서드를 람다식으로 구현한건지 모호하다.

그렇기에 함수형 인터페이스 내에는 단 하나의 메서드만을 선언해야 한다.

@FunctionalInterface 애노테이션(annotation)은 함수형 인터페이스라는 것을 명시하기 위해 인터페이스 위해 작성한다.



4. 람다식 구현과 호출

위에서 작성한 함수형 인터페이스를 통해서 람다식을 구현하고, 호출해보자.

public class TestMyNumber {

	public static void main(String[] args) {
		MyNumber max = (x, y)->(x>= y)? x:y; // 람다식을 인터페이스 자료형 max 변수에 대입

		System.out.println(max.getMax(10, 20));// 인터페이스 자료형 변수로 함수 호출
			
	}
}

위 코드는 람다식을 변수에 대입한 후 호출한 코드이다.


이를 통해 알 수 있겠지만 람다식은 함수를 변수처럼 사용할 수 있다.


함수를 변수처럼 사용할 수 있다는 것을 아래 예시를 통해 조금 더 알아보자.

@FunctionalInterface
interface PrintString{
	
	void showString(String str);

}

위와 같이 함수형 인터페이스를 선언한 후, 변수는 특정 자료형으로 변수를 선언하고 값을 대입할 수 있다.

PrintString lambdaStr = s->System.out.println(s);  //람다식을 변수에 대입
lambdaStr.showString("hello lambda_1");
  • 위 코드는 인터페이스형 변수에 람다식을 대입하는 코드이다.

또한 변수(람다식)는 매개 변수로 전달하여 사용할 수 있다.

PrintString lambdaStr = s->System.out.println(s);

showMyString(lambdaStr); 

public static void showMyString(PrintString p) {
	p.showString("hello lambda_2");
}
  • 위 코드는 매개변수로 전달하는 람다식이다.

그리고 변수(람다식)는 메서드의 반환 값으로도 반환할 수 있다.

public static PrintString returnString() {         //반환 값으로 사용
		return s->System.out.println(s + "world");
}

PrintString reStr = returnString();  
reStr.showString("hello ");
  • 위 코드는 반환 값으로 쓰이는 람다식이다.
profile
Hello, World! \n

0개의 댓글

관련 채용 정보