- 함수(메서드)를 간단한 '식(expression)'으로 표현하는 방법
int max(int a, int b) { return a > b ? a : b; }
--> (a, b) -> a>b ? a:b- 익명 함수(이름이 없는 함수, annoymous function)
int max(int a, int b) { return a > b ? a : b; }
-->int max(int a, int b) -> { return a > b ? a : b; }- 함수와 메서드의 차이
->근본적으로 동일. 함수는 일반적 용어, 메서드는 객체지향개념 용어
->함수는 클래스에 독립적, 메서드는 클래스에 종속적
- 메서드의 이름과 반환타입을 제거하고 ' -> '를 블록{} 앞에 추가
int max(int a, int b) { return a > b ? a : b; }
-->int max(int a, int b) -> { return a > b ? a : b; }- 반환값이 있는 경우, 식이나 값만 적고 return문 생략 가능(끝에 ' ; ' 안붙임)
(int a, int b) -> {return a>b ? a : b; }
--> (int a, int b) -> a>b ? a : b- 매개변수의 타입이 추론 가능하면 생략가능(대부분의 경우 생략가능)
(int a, int b) -> a>b ? a : b
--> (a, b) -> a>b ? a : b
- 매개변수가 하나인 경우, 괄호() 생략가능(타입이 없을 때만)
(a) -> a * a --> a -> a * a // Ok (int a) -> a * a int a -> a * a // 에러
- 블록 안의 문장이 하나뿐 일 때, 괄호{}생략가능(끝에 ';' 안붙임)
(int i) -> {System.out.println(i);} --> (int i) -> System.out.println(i)
예제>
- 람다식은 익명 함수가 아니라 익명 객체이다!
- 람다식(익명 객체)을 다루기 위한 참조변수가 필요. 참조변수의 타입은?
- 함수형 인터페이스 - 단 하나의 추상 메서드만 선언된 인터페이스
@FunctionalInterface // 생략 가능 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 value = f.max(3,5); // Ok. MyFunction에 max()가 있음
- 함수형 인터페이스 타입의 참조변수로 람다식을 참조할 수 있음
(단, 함수형 인터페이스의 메서드와 람다식의 매개변수 개수와 반환타입이 일치해야함)
- 자주 사용되는 다양한 함수형 인터페이스를 제공
- 매개변수가 2개인 함수형 인터페이스
(bi는 두개를 의미)
- 매개변수의 타입과 반환타입이 일치하는 함수형 인터페이스
- andThen()
-> Function타입의 두 람다식을 하나로 합성Function<String, Integer> f = (s) -> Integer.parseInt(s, 16); // s를 16진 정수로 변환 Function<Integer, String> g = (i) -> Integer.toBinaryString(i); // 2진 문자열로 변환 Function<String, String> h = f.andThen(g); // f + g ->h ... System.out.println(h.apply("FF")); // "FF" -> 225 -> "11111111"
- compose()
-> Function타입의 두 람다식을 하나로 합성Function<String, Integer> f = (s) -> Integer.parseInt(s, 16); Function<Integer, String> g = (i) -> Integer.toBinaryString(i); Function<Integer, Integer> h = f.compose(g); // =g.andThen(f)
- and()-&&, or()-||, negate()-! 로 두 Predicate를 하나로 결합(default메서드)
- 등가비교를 위한 Predicate의 작성에는 isEqual()를 사용(static메서드)
Predicate<String> p = Predicate.isEqual(Str1); // isEqual()은 static 메서드 Boolean result = p.test(str2); // str1과 str2가 같은지 비교한 결과를 반환 --> boolean result = Predicate.isEqual(str1).test(str2);
- 하나의 메서드만 호출하는 람다식은 '메서드 참조'로 더 간단히 할 수 있다.
- 클래스이름 :: 메서드이름
- static메서드 참조
- 생성자와 메서드 참조
Supplier<MyClass> s = () -> new MyClass(); -> Supplier<MyClass> s = MyClass::new; .. Function<Integer, MyClass> s = (i) -> new MyClass(i); -> Function<Integer, MyClass> s = MyClass::new;
- 배열과 메서드 참조
Function<Integer, int[]> f = new int[x]; // 람다식 Function<Integer, int[]> f2 = int[]::new; // 메서드 참조
🚀 출처
자바의 정석 책 & 유튜브