- Java = OOP(객체지향)언어 + 함수형언어(JDK1.8부터)
- 함수(메서드)를 간단한 '식'(expression)으로 표현하는 방법
int max(int a, int b) { return a > b ? a : b -> (a,b) -> a > b ? a : b }
- 익명 함수(이름이 없는 함수, annomymous function)
int max(int a, int b) { (int a, int b) -> { // 반환타임과 이름을 지우고 ->가 추가된다. return a > b ? a : b; -> return a > b ? a : b; } }
- 함수와 메서드의 차이
- 근본적으로는 동일. 함수는 일반적 용어, 메서드는 객체지향개념 용어
- 함수는 클래스에 독립적, 메서드는 클래스에 종속적
- 1.메서드의 이름과 반환타입을 제거하고 '->'를 블록{} 앞에 추가한다.
int max(int a, int b) { (int a, int b) -> { // 반환타임과 이름을 지우고 ->가 추가된다. return a > b ? a : 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 -----> int a -> a * a // 에러
- 2.블록 안의 문장이 하나뿐 일 때, 괄호{}생략가능(끝에';'안 붙임)
(int i) -> { System.out.println(i); ---> (int i) -> System.out.println(i) }
단, 하나뿐인 문장이 return문이면 괄호{} 생략 불가
(int a, int b) -> { return a > b ? a : b; } // OK (int a, int b) -> return a > b ? a : b; // 에러
1. (a,b) -> a > b ? a : b
2. (name,i) -> System.out.println(name+"=+i)
3. x -> x x
4. () -> (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()가 없음
- 함수형 인터페이스 : 단 하나의 추상 메서드만 선언된 인터페이스
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()가 있음
- 함수형 인터페이스 타입의 참조변수로 람다식을 참조할 수 있음.
(단, 함수형 인터페이스의 메서드와 람다식의 매개변수 구ㅐ수와 반환타입이 일치해야 함.)MyFunction f = (a, b) -> a > b ? a : b; int value = f.max(3,5); // 실제로는 람다식(익명 함수)이 호출됨
- 익명 객체를 람다식으로 대체
↓List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "aaa"); Collections.sort(list,(s1,s2) -> s2.compareTo(s1));
interface Compareto<T> { int compare(T o1, T o2); }
- 함수형 인터페이스 타입의 매개변수
void aMethod(MyFunction f) { f.myMethod(); // MyFunction에 정의된 메서드 호출 }
MyFunction f = () System.out.println("myMethod()"); aMethod(f);
↓
aMethod( () -> System.out.println("myMethod()"));
- 함수형 인터페이스 타입의 반환타입
MyFunction myMethod() { MyFunction f = () -> {}; ----> MyFunction myMethod() { return f; return () -> {} } }