오늘도 여전히 자바의 정석 : 챕터 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 //에러
여기서 헷갈리는 부분은 ;
를 넣었다 뺏다 하는 것.... 인텔리제이를 사용한다면 알아서 에러를 내주겠지만.. ㅎ 손으로 코딩하려니 헷갈린다....
람다식을 다루기 위해 인터페이스를 사용하기로 했는데 이 인터페이스를 함수형 인터페이스라 한다.
이 함수형 인터페이스는 오직 하나의 추상 메서드만 정의되어야 한다.
그래야 람다식과 인터페이스의 메서드가 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 패키지에 있는 함수형 인터페이스들
컬렉션 프레임워크의 인터페이스에 다수의 디폴트 메서드가 추가되었는데
그 중의 일부는 함수형 인터페이스를 사용한다고 한다.
이 부분은 직접 책과 유튜브 강의를 보는게 좋을 듯 하다!
자바의 정석 - 기초편 ch14-9~11 해당 링크는 9~11 이지만 7~14까지의 내용을 들어야한다 ㅎㅎ