[자바의 정석] 14. 람다와 스트림 - 람다식

jyleever·2022년 9월 19일
0

자바의 정석

목록 보기
5/12
post-thumbnail
  • 자바는 OOP 언어인데, 1.8부터 함수형 언어의 기능을 추가시켰다.
    참고로 Haskell, Erlang, Scala... 등의 함수형 언어는 빅데이터가 뜨면서 각광 받고 있다.

람다식

함수(메서드)를 간단한 식(expression)으로 표현하는 방법

int max(int a, int b){
	return a > b ? a : b;
}

(a, b) -> a > b ? a : b

메서드를 람다 식으로 바꿀 때에는
반환 타입과 이름을 지운다.
그리고 그 사이에 화살표를 넣는다! -> 익명 함수, anonymous function

😉 함수와 메서드의 차이

  • 근본적으로 동일, 함수는 일반적 용어, 메서드는 객체지향개념 용어
  • 함수는 클래스에 독립적, 메서드는 클래스에 종속적
    (클래스 안에 포함되어있으면 메서드, 클래스 밖에 있으면 함수~ 자바에서는 클래스 밖에 있을 수 없죠? 전부 다 메서드! 이 강의에서는 그냥 구분하지 않고 사용할 것)

람다식 작성하기

바꾸는 규칙을 너무 어려워하지 말자.😎

1. 메서드의 이름과 반환 타입을 제거하고 ->을 블록 {} 앞에 추가한다.

int max(int a, int b){
	return a > b ? a : b;
}(int a, int b) -> {
	return a > b ? a : b;
}

2. 반환값이 있는 경우, 식이나 값만 적고 return문 생략 가능 (끝에 ; 안 붙임)

(int a, int b) -> {
	return a > b ? a : b;
}(int a, int b) -> a > b ? a : b

3. 매개변수의 타입이 추론 가능하면 생략 가능(대부분의 경우 생략 가능)

(int a, int b) -> a > b ? a : b
↓
(a, b) -> a > b ? a : b

람다식 작성하기 - 주의 사항

1. 매개변수가 하나인 경우, 괄호() 생략 가능(타입이 없을 때만)

(a) -> a * a ➡ a -> a * a // OK
(int a) -> a * a ➡ a -> a * a // 에러

2. 블록 안의 문장이 하나뿐일 때, 괄호 {} 생략 가능 (끝에 ; 안 붙임)

(int i) -> {
	System.out.println(i);
}(int i) -> System.out.println(i)

람다식의 예

int max(int a, int b){
	return a > b ? a : b
}(a, b) -> a > b ? a : b
int printVar(String name, int i){
	System.out.println(name += "=" + i);
}(name, i) -> System.out.println(name+"="+i)
int square(int x){
	return x*x;
}
↓
x -> x*x
int roll(){
	return (int) (Math.random()*6);
}() -> (int)(Math.random()*6)

람다식은 익명 함수? 익명 객체!

람다식은 익명 함수가 아니라 익명 객체이다.

(a, b) -> a > b ? a : b

위 람다식은 아래 익명 클래스, 익명 객체와 같다.
즉, 객체의 선언과 생성을 동시에 하는 익명 클래스

new Object(){
	int max(int a, int b){
    	return a > b ? a : b;
    }
}
  • 람다식(익명 객체)을 다루기 위한 참조 변수가 필요, 참조 변수의 타입은?
Object obj = new Object(){
	int max(int a, int b){
    	return a > b ? a : b;
    }
}

여기서 문제가 발생! 타입 obj = (a,b) -> a > b ? a : b // 어떤 타입?

  • int value = obj.max(3,5) : 에러가 뜬다. Object 클래스에는 max() 가 없기 때문!
  • 즉, 실제로 분명히 이 객체가 max 메서드를 가지고 있어도 참조 변수인 Object에서는 max 메서드가 없으므로 호출할 수가 없다.
    -> 어떻게 해야하는지는 다음 강의에서~
Object obj = new Object(){
	int max(int a, int b){
    	return a > b ? a : b;
    }
}; // 익명 객체

int value = obj.max(3, 5); // 에러

이렇게 Object에서 존재하지 않은 메서드로 접근하기 때문에 에러가 발생하므로 여기서 함수형 인터페이스가 필요하다. 다음 강의에서~

  • 람다식은 메서드를 간단히 한 것이긴 하지만, 자바라는 언어 특성 상 모든 메서드는 객체 안에 존재해야 하므로 익명 객체 안에 메서드를 넣어준다.
  • 람다식을 다루기 위해서는 타입에 관한 개념이 있어야 한다. Object 하나 가지고는 다룰 수 없다 -> 함수형 인터페이스

0개의 댓글