람다

Drumj·2023년 2월 22일
0
post-thumbnail

오늘의 학습

오늘도 여전히 자바의 정석 : 챕터 14 람다와 스트림을 공부하면서 정리해보자.
부트캠프를 할 때도 정확히 모르고 넘어갔고... 일을 하는 중에도 생긴거 보면 '아~ 이거 람다지!' 결과는 어떻게 나오겠다~~ 라고 예상은 할 수 있지만 익명 함수가 뭐고 그게 왜 이렇게 작성이 되고 뭐뭐 가 생략되고 어쩌고 저쩌고 블라블라(블라인드)...여튼 몰랐던 것을 하나하나 알아가 보도록 하자!!


람다식

간단히 말해서 메서드 를 하나의 식(expression)으로 표현한 것.
메서드를 람다식으로 표현하면 메서드의 이름과 반환값이 없어지므로 익명 함수(anonymous function)라고도 한다.

메서드를 호출하려면 클래스도 새로 만들고 객체도 생성해야 하지만, 람다식은 이 모든 과정없이 그 자체만으로도 메서드의 역할을 대신할 수 있다.
람다식으로 인해 메서드를 변수처럼 다루는 것이 가능해진 것.


람다식 작성하기

가장 궁금했던 부분! 뭐야??? (어떻게 이게 생략되고 작성하는 거야!!!)

메서드를 람다식으로 만드는 방법은 아주 간단했다..

메서드 이름과 반환타입을 제거하고 매개변수 선언부몸통{} 사이에 ->를 추가하면 끝!!
바로 코드를 보면서 알아보자.

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

//람다식 1. 반환타입, 이름 제거
(int a, int b) -> { return a > b ? a : b;}

//람다식 2. return 제거
(int a, int b) -> a > b ? a : b // 이때는 문장이 아닌 식이므로 끝에 ;를 생략한다고 한다.

//람다식 3. 매개변수의 타입이 추론가능해서 생략.
(a, b) -> a > b ? a : b 

//람다식 4. 선언된 매개변수가 하나뿐이라면 ()도 생략가능. 단, 타입이 있으면 생략불가
(a) -> a*a       =>    a -> a*a //가능
(int a) -> a*a   =>    int a -> a*a // int 가 있어서 불가능!

//람다식 5. 이미 위에서부터 보였지만 {} 도 생략가능하다. 괄호안의 문장이 하나일 경우만.
(String name, int i) -> {System.out.println(name + "=" + i);}
=>
(String name, int i) -> System.out.println(name + "=" + i) //끝에 ;도 없어진다.
//단, return문일 경우 불가
(int a, int b) -> { return a > b ? a : b;} //OK
(int a, int b) -> return a > b ? a : b //에러

여기서 헷갈리는 부분은 ;를 넣었다 뺏다 하는 것.... 인텔리제이를 사용한다면 알아서 에러를 내주겠지만.. ㅎ 손으로 코딩하려니 헷갈린다....


함수형 인터페이스(Functional Interface)

람다식을 다루기 위해 인터페이스를 사용하기로 했는데 이 인터페이스를 함수형 인터페이스라 한다.

이 함수형 인터페이스는 오직 하나의 추상 메서드만 정의되어야 한다.
그래야 람다식과 인터페이스의 메서드가 1:1로 매칭될 수 있기 때문이라고 한다.

역시 글로는 알기 힘들다... 개발자는 코드로 알아보도록 하자.

// 인터페이스
interface MyFunction {
	public abstract int max(int a, int b)
}

//인터페이스를 구현한 익명 클래스의 객체 생성
MyFunction f = new MyFunction() {
					public int max(int a, int b) {
    					return a > b ? a : b;
        			}
        	   };

int big = f.max(5,3); //익명 객체의 메서드를 호출

//람다식으로 변경
MyFunction f = (int a, int b) -> {a > b ? a : b;} // 책의 예제는 {} 이 생략 됬지만 나는 {}을 넣는게 더 좋다. 만약 이게 안되는 거라면 알려주십셔...
int big = f.max(5,3); //익명 객체의 메서드를 호출

자 이렇게 대충 흐름을 알아봤다.
우선 인터페이스를 만들고 익명 클래스를 활용해서 다시 람다식으로 바꾸는 과정!!

// 함수형 인터페이스
@FunctionalInterface // 이 애노테이션을 달아주자!
interface MyFunction {
	public abstract int max(int a, int b)
}

마지막으로 애너테이션까지 추가! 사실 없어도 상관은 없다. 하지만 달아놓으면 메서드가 하나 더 추가 되는 걸 방지할 수 있겠죠잉??


그 외에도..

java.util.function 패키지에 있는 함수형 인터페이스들

  • java.lang.Runnable
  • Supplier<T>
  • Consumer<T>
  • Function<T,R>
  • Predicate<T>

컬렉션 프레임워크의 인터페이스에 다수의 디폴트 메서드가 추가되었는데
그 중의 일부는 함수형 인터페이스를 사용한다고 한다.

이 부분은 직접 책과 유튜브 강의를 보는게 좋을 듯 하다!
자바의 정석 - 기초편 ch14-9~11 해당 링크는 9~11 이지만 7~14까지의 내용을 들어야한다 ㅎㅎ

0개의 댓글