람다 스트림

이재현·2024년 8월 1일

Java

목록 보기
14/15

🩵 Lambda Expression

과거에서 현재에 이르기까지, 데이터의 측면에서 현재는 AI와 빅 데이터 세상이 오면서, 큰 데이터를 잘 다루는 것이 매우 중요하게 되었다.

자바의 Collection은 우수한 성능을 자랑했지만, Terabyte 혹은 거의 무한한 크기의 데이터 셋을 다루기엔 불편한 점이 많다.

이러한 점에서 병렬성의 활용과 간결한 코드를 위해서, Java 8 이후로 아래 기술들이 도입되었다.

  • 메서드의 1급 시민화
  • 스트림 API
  • 인터페이스의 디폴트 메서드

디폴트 메서드를 활용한 컬렉션 강화
거대한 컬렉션을 분산 환경에서 다루기 위한 병렬화 기술 강화
컬렉션을 좀 더 효율적으로 다루기 위한 스트림 강화
스트림의 용이한 사용을 위한 선언형-함수형 프로그래밍 도입
선언형-함수형 프로그래밍 위한 람다 도입


데이터셋의 복잡화로 인해 기존 방식의 불편함이 드러나게 되었다.

기존 for문을 이용해 순회하며, 내부적으로 if문을 사용하고, 또 그 안에서 for문을 사용하고, 분기하고, …

이러한 불편함을 해결하고 스트림을 편리하게 사용하기 위해서 선언형-함수형 프로그래밍이 도입되었다.

스트림은 이 자료구조로 무엇을 할지에 집중할 수 있게 해주고, 어떻게 할지에 대해서는 따로 생각할 수 있게 해준다.




🩵 Lambda

람다"식"은 메서드를 하나의 "식"으로 표현한 것이고, 또한 일종의 코드 블록이다.

람다식을 적용하면 메서드의 이름과 반환값이 없어진다.

그래서 람다를 이름이 없다는 의미로 익명함수라고도 부르는 것이다.


💙 Lambda 의 구조

람다는 (매개변수 목록) -> (로직) 의 구조를 갖는다.
메서드의 정의와는 다르게, 이름이 없고, 반환 타입이 없다.

// 일반 메서드
int max(int a, int b) {
return a > b ? a : b;
}

// 람다식
(int a, int b) -> {
  return a > b ? a : b;
}

이와 같이 이름 max 와 반환 타입 int 를 제거할 수 있다.
또한 매개 변수와 메서드 바디는 화살표 -> 를 사용하여 이었다.
Return값 역시, Java의 Type Inference로 매개 변수의 타입으로 반환 타입을 추론하여 지울 수 있다.

(a, b) -> a > b ? a : n // 매개변수가 하나라면 소괄호도 지울 수 있다!

람다의 모든 매개변수 타입은 생략하는 것이 좋다.
(타입을 명시해야 코드가 더 명확한 경우나, 컴파일러가 타입을 판단할 수 없는 경우 제외)

특히 매개변수 이름이 매우 긴 경우에 유용하다.

람다를 적극적으로 활용하면 메서드를 다양한 방식으로 좀 더 간결하게 나타낼 수 있다.

다만, 우리가 평소 사용하는 메서드들을 정의하기 위해 이런 람다를 사용하는 것은 아니다.

익명 객체와 똑같이, 위 사진과 같이 한번 쓰고 버릴 메서드가 있다면, 람다로 간단하게 정의해 사용할 수 있다.


💙 Enum Factoring Using Lambda

// 기존 Enum 팩토링
public enum Operation {
	ADDITION(+) {
	public double apply(double x, double y) {
	return x + y;
}
}
	SUBTRACT(-) {}
	MULTIPLY(*) {}
	DIVIDE(/) {}
}

// 람다를 활용한 Enum 팩토링
public enum Operation {
	ADDITION(+, (x , y) -> x + y),
	SUBTRACT(-, (x , y) -> x - y),
	MULTIPLY(*, (x , y) -> x * y),
	DIVIDE(/, (x , y) -> x / y);

	Private final DoubleBinaryOperator doubleBinaryOperator;

	Public double apply(double x, double y) {
		return doubleBinaryOperator.applyAsDouble(x, y);
}
}

와.. 개깔끔..!
기존 자바의 모든 정의는 클래스 안에서만 이루어질 수 있었다.
따라서 메서드는 어딘가의 클래스에 포함되어야 하기 때문에, 여러 제약들이 많았다.
정의하기 위해 클래스를 만들어야 했고, static이 아닌 경우 호출을 위한 객체도 만들어야 했다.

람다식과 메서드 레퍼런스로 메서드는 이제 주고받을 수 있는 값인 1급 값이 되었다.
즉, 메서드를 변수처럼 다루는 것이 가능해진 것이다.




🩵 1급과 동작의 파라미터화

동작의 파라미터화는 어떤 코드로 작성된 메서드로 표현되는 동작을 다시 메서드의 파라미터로 사용할 수 있다는 것을 의미한다.

예전의 자바는 주고받을 수 있는 값은 primitive 값과, 객체의 인스턴스의 주소, 래퍼런스 값이었다. 변수에 할당하거나, 메서드의 파라미터로 설정하여 주고받거나, 반환값으로써 사용할 수 있었다.

0개의 댓글