기존 코드는 유지한 채 요구사항을 변경하는 프레디케이드를 구현하는 클래스를 만들면 된다.
(아래의 p가 프레디케이드)
predicate(프레디케이드)
: boolean을 반환하는 함수
단점 : 여러 클래스를 구현해야 함. 인스턴스화하는 과정 불편
public static List<Apple> filter(List<Apple> inventory, ApplePredicate p) {
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory) {
if (p.test(apple)) {
result.add(apple);
}
}
return result;
}
즉석에서 필요한 구현 만들어 사용한다.
단점 : 불필요한 공간 차지, 장황함, 낮은 가독성, 이해하기 어려움
//부모
abstract class Parent {
abstract String test() {}
}
//인터페이스
interface Human {
public void humanFunc();
}
//자식(없어도 가능)
abstract class Child extends Parent {
}
new Person() {
void func() {
}
}.func();
Person p = new Person() {
void func() {
System.out.println("person");
}
};
p.func();
new Human() {
public void humanFunc() {
System.out.println("human");
}
}.humanFunc();
익명 클래스 사용 시 abstract 하거나 interface 여야 함.
함수를 1급 객체처럼 다룰 수 있게 함. 인터페이스 선언 & 하나 추상 메서드만 가짐.
람다식은 함수적 인터페이스에서 사용한다.
변수나 데이터 구조 안에 담을 수 있다.
파라미터로 전달할 수 있다.
반환값으로 사용할 수 있다.
할당에 사용된 이름과 무관하게 고유한 구별이 가능하다.
인터페이스에 선언하여 딱 하나 추상 메서드만을 갖도록 제한
어노테이션 @FunctionalInterface을 사용해서 함수형 인터페이스로 정의 가능
@FunctionalInterface
interface Func{
int max(int a, int b);
}
public class Lambda {
public static void main(String[] args) {
Func func = (int a, int b) -> a > b ? a : b;
System.out.println(func.max(3, 5));
}
}
써서 이득 : 아직 찾지 못함
써서 손해 : 아직 찾지 못함
위의 단점 나열하고 이를 타개하기 위해 람다를 사용한다.
메서드로 전달할 수 있는 익명 함수를 단순화한 것
위에 비해 간단해지고 문제를 더 잘 설명 가능하다.
x -> x*x
(x) -> System.out.println(x);
x -> System.out.println(x);
(x,y) -> System.out.println(x + y);
// 안됨!
(int x, y) -> System.out.println(x + y);
() -> System.out.prinln("Hi!");
() -> {}
(int a, int b) -> a > b ? a : b;
(i,j) -> { return i+j; };
*추가
이거 컴파일 안되는 이유
Object o = () -> {
System.out.println("Tricky example");
};
Object(대상 형식)이지만 함수형 인터페이스가 아님.
→ Runnable로 대상 형식을 바꿔서 해결 가능
→ Runnable이 lambda의 void 같은 의미
람다식 아닌 일반 메서드 참조 선언
일반, static, 생성자, 클래스이름::메소드이름 등 java에서 지원함.
Function<Integer, Double> = a -> (Double)a;
BiFunction<Integer, Integer, Double> = (a, b) -> (Double)a/b;
람다 내부에서 외부 변수를 수정할 때 에러가 발생
람다식을 작성하면 메모리에서 만들어질 때 stack을 캡처링(복사같은 느낌) 한다. 람다식은 캡처링한 내용을 사용함
람다 외부 변수는 참조만 가능하다.