Java Lambda 관련 정리 from 이것이 자바다(책)
Updated:
Java Lambda
Lambda : 익명 함수(anonymous function)을 생성하기 위한 식으로, 객체 지향 언어보다는 함수 지향 언어에 가까움
그런데 왜 자바에서 이런 람다식을 수용한 것인가?
- 자바 코드가 매우 간결해짐
- 컬렉션의 요소를 필터링하거나 매핑해서 결과 집계를 쉽게 가능하게 함
// 람다식 -> 매개 변수를 가진 코드 블록 -> 익명 구현 객체
Runnable runnable = new Runnable() { // new 부터의 형태가 익명 구현객체이다
@Override
public void run() {
//어쩌고..
}
};
// 그러나 람다식으로 가게 되면
Runnable runnable = () -> {...};
기본 문법
// (타입 매개변수, ...)->{실행문; ...}
(int a) -> {System.out.println(a);}
// 매개변수타입은 런타임시에 자동으로 인식되어서, 일반적으로는 매개변수타입은 넣지 않는다
(a)->{System.out.println(a);}
// 매개변수가 1개이고, 만약 실행문이 한개면 ()괄호와 {}괄호는 생략이 가능하다
a->System.out.println(a);
(x,y)->{return x+y;} // 만약 리턴문이 있는데, 리턴문만 있다면
(x,y)-> x+y ; // 로 바꿀수있다.
람다식은 하나의 메소드를 정의하기 때문에, 두 개 이상의 추상 메소드가 선언된 인터페이스는 람다식을 이용해서 구현 객체를 생성할수 없다. 그래서 하나의 추상 메소드만 가능하다. (여기서 착각하지 말아야 할 부분은 디폴트 메소드나 정적 메소드는 포함이 되지않는다. 즉, 디폴트 메소드와 정적 메소드는 몇개 이상이 추가되어도 상관이 없다는 말임)
이 때, 함수적 인터페이스를 작성할때, 두 개 이상의 추상 메소드가 선언되지 않도록 컴파일러가 체킹해주는 기능이 있다. @Functional 이라는 annotation을 붙이면 된다
@FunctionalInterface
public interface MyFunctionalInterface {
public void method();
public void otherMethod(); // 컴파일 에러
}
함수적 인터페이스는 크게 Consumer, Supplier, Function, Operator, Predicate로 구분된다. 구분 기준은 인터페이스에 선언된 추상 메소드의 매개값과 리턴값의 유무이다.
저 인터페이스들을 이용해서 그냥 각각의 경우만 처리하면 그닥 큰 쓸모가 없을수도 있다. 그래서 Consumer, Function, Operator 종류의 함수적 인터페이스는 andThen()과 compose() 디폴트 메소드를 가지고 있다.
먼저 andThen()의 경우는, 첫번째 인터페이스의 일을 먼저 처리한후, 두 번째 매개값으로 제공해 최종 결과를 얻을 때 사용
인터페이스AB = 인터페이스A.andThen(인터페이스B); // 인터페이스A의 메소드를 먼저 실행한뒤에 인터페이스 B의 메소드를 실행
최종결과 = 인터페이스AB.method();
인터페이스AB = 인터페이스A.compose(인터페이스B); // 인터페이스B의 메소드를 먼저 실행한뒤에 인터페이스 A의 메소드를 실행
최종결과 = 인터페이스AB.method();
메소드 참조(Method References) : 말 그대로 메소드를 참조해서 매개 변수의 정보 및 리턴 타입을 알아내어, 람다식에서 불필요한 매개 변수를 제거하는 것이 목적이다.
(left,right) -> Math.max(left,right); // Lambda Expression
Math::max; // Method References
메소드 참조도 람다식과 마찬가지로 인터페이스의 익명 구현 객체로 생성이 된다.
클래스이름 :: 메소드 // static(정적) 메소드를 참조할 경우
참조변수 :: 메소드 // 인스턴스 메소드를 참조할경우, 저기서 참조변수는 사실상, new 연산자로 할당된 인스턴스 이름을 의미할것이다.
클래스 :: new // (a,b) -> return new 클래스(a,b); 만약 해당 생성자가 존재하지 않으면 컴파일 에러!!
위와 관련한 모든 예제들은 아래 링크 주소에 있으니 참고해주시면 감사하겠습니다.
https://github.com/goodgood619/ThisIsJava
Leave a comment