Inflearn

인프런 워밍업 클럽 0기 - BE 3일차 과제

느리지만 꾸준하게 2024. 2. 21. 21:57

 

[키워드]

익명 클래스 / 람다 / 함수형 프로그래밍 / @FunctionalInterface / 스트림 API / 메소드 레퍼런스

 

 

[질문]

  • 자바의 람다식은 왜 등장했을까?

람다식(Lambda Expression)이란 무엇인가?

Stream 연산들은 매개변수로 함수형 인터페이스(Functional Interface)를 받도록 되어있다. 그리고 람다식은 반환값으로 함수형 인터페이스를 반환하고 있다. 그렇기 때문에 우리는 Stream API를 정확히 이해하기 위해 람다식과 함수형 인터페이스에 대해 알고 있는것이 좋다.

 

람다식(Lambda Expression)이란 함수를 하나의 식(expression)으로 표현한 것이다. 함수를 람다식으로 표현하면 메소드의 이름이 필요 없기 때문에, 람다식은 익명 함수(Anonymous Function)의 한 종류라고 볼 수 있다.

 

익명함수(Anonymous Function)란 함수의 이름이 없는 함수로, 익명함수들은 모두 일급 객체이다. 일급 객체인 함수는 변수처럼 사용가능하며 매개 변수로 전달이 가능하는 등의 특징을 가지고 있다.

 

메서드를 매개변수로 전달하기 위해 자바 8에서 도입된 기능이 람다식.

인스턴스화를 거친 후에 메소드를 전달했던 불편한 부분을 람다식으로 해결 가능.

또한, 함수형 인터페이스의 인스턴스를 생성하여 함수를 변수처럼 선언하는 람다식은 불필요한 코드를 줄이고, 가독성이 높아짐.

 

출처 : https://mangkyu.tistory.com/113

https://wandering-chance-47d.notion.site/2-21-a397e3eefc864bdf90fe4849bb29c49a?pvs=4

 

 

 

 

 

익명 구현 클래스 vs 람다식

그렇다면 익명클래스와 람다식의 차이는 무엇일까.

1. 익명 내부 클래스는 새로운 클래스를 생성하지만, 람다는 새로운 메서드를 생성하여 포함한다.

  • 람다는 static 이든, 객체 사용을 위한 non-static 이든, 메서드로 생성된다.
  • 이에 반해 익명 내부 클래스는 새로운 클래스파일이 생성된다.

 

 

2. 익명 내부 클래스의 this : 새로 생성된 클래스, 람다의 this : 람다식을 포함하는 클래스

  • 위와 완벽하게 일맥상통하는 말이다.
  • 새로운 클래스를 만들기 때문에, 익명 내부클래스에서의 this 는 해당 클래스를 가리킨다.
  • 새로운 클래스를 만드는 게 아니고 그냥 메서드를 만드는 람다는, 메서드 즉 람다가 있는 클래스를 가리킨다.

 

출처 : https://gimmesome.tistory.com/209

 

 

3. 람다식은 어떻게 사용할까?

 

 

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

MyFunctionalInterface mi = () -> System.out.println("덧셈 함수입니다.");
mi.sum();

 

매개 변수와 리턴값이 없을 경우 '() -> {}' 형태로 람다식을 기술하면 됩니다. 만약, 중괄호 안에 실행문이 하나일 경우 중괄호를 제거할 수 있습니다. 이렇게 인터페이스 객체를 정의한 후에, 객체가 가지고 있는 메소드를 호출하면 됩니다. 실행 결과는 "덧셈 함수입니다."가 나온다.

 

 

2. 매개 변수가 있는 람다식

MyFunctionalInterface mi = (x, y) -> System.out.println(x + " + " + y + " = " + (x + y));
mi.sum(3, 6);

 

MyFunctionalInterface에서 sum 메소드에 매개 변수 int x와 int y를 추가해 준다.

 

그리고 메인 함수에서는 아래와 같이 인터페이스 객체를 정의해 주고, 객체가 가지고 있는 메소드를 호출하면 됩니다. 출력 결과는 "3 + 6 = 9"가 될 것이다.

 

 

 

3. 매개 변수와 리턴값이 있는 람다식

@FunctionalInterface
public interface MyFunctionalInterface {
	public int sum(int x, int y);
}

 

MyFunctionalInterface에서 sum 메소드에 리턴 타입을 int로 정의해 준다.

 

그리고 메인 함수에서는 아래와 같이 인터페이스 객체를 정의해 주고, 객체가 가지고 있는 메소드를 호출하면 되고, 출력 결과는 "9"가 나온다.

 

MyFunctionalInterface mi = (x, y) -> x + y;
System.out.println(mi.sum(3, 6));

 

중괄호 블록 안에 실행문이 return뿐 일 때는 위와 같이 중괄호와 return문을 동시에 생략이 가능하다.

 

출처 : https://steady-coding.tistory.com/304