💡 람다 : 익명 메소드만 전달하여, 인터페이스르 구현한 익명 클래스의 인스턴스를 생성하는 방법, 메소드만 전달하지만, 결과적으로 익명 구현 객체를 만듬
💡 익명 클래스 : 추상 클래스를 상속하거나 인터페이스를 구현한 이름 없는 클래스, 재사용이 필요없는 인스턴스를 생성할 때 사용
익명 클래스 | 람다 표현식 |
---|---|
이름 없는 클래스 | 이름이 없는 메소드 |
추상 및 구체 클래스를 확장 가능 | 추상 및 구체 클래스 확장 불가능 |
여러 추상 메소드를 포함하는 인터페이스 구현 가능 | 단일 추상 메소드를 포함하는 인터페이스 구현 가능 |
익명 클래스 내부에서 인스턴스 변수 선언 가능 | 인스턴스 변수 선언 불가능 |
인스턴스화 가능 | 인스턴스화 불가능 |
this 키워드 현재 익명 클래스 객체 참조 | this 키워드 현재 외부 클래스 |
public static void anonymousClass() {
ArrayList<String> words = new ArrayList<>(List.of("a", "b", "c"));
Collections.sort(words, new Comparator<String>(){
@Override
public int compare(String o1, String o2) {
return Integer.compare(o1.length(), o2.length());
}
});
}
익명 클래스 방식은 코드가 너무 길어지기 때문에 함수형 프로그래밍에 적합하지 않다.
public static void lambda() {
ArrayList<String> words = new ArrayList<>(List.of("a", "b", "c"));
Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length()));
}
익명 클래스와 개념은 비슷하지만 코드가 훨씬 간결해진다!
위와 같이 Type
을 명시하지 않아도 사용 가능한 이유는 컴파일러가 대신 인터페이스에 대한 타입을 추론 해주기 때문이다!
대부분 제네릭을 통해 얻는다!
public enum Menu {
COFFEE("커피", money -> money * 2),
CAKE("케이크", money -> money),
TEA("차", money -> money * 3);
private final String name;
private final Function<Integer, Integer> op;
Menu(String name, Function<Integer, Integer> op) {
this.name = name;
this.op = op;
}
public int price(int money) {
return op.apply(money);
}
public String getName() {
return name;
}
}