Ch14-5~6. 함수형 인터페이스
0. 목차
Chapter14. 람다와 스트림
Ch14 - 5. 함수형 인터페이스(Functional Interface)
Ch14 - 6. 함수형 인터페이스 타입 매개변수, 반환타입
Ch14 - 5. 함수형 인터페이스(Functional Interface)
▶ 함수형 인터페이스(Functional Interface)란?
▷ 단 하나의 추상 메서드만 선언 된 인터페이스
interface MyFunction {
public abstract int max(int a, int b); // 추상 메서드 하나 → 함수형 인터페이스
}
// 함수형 인터페이스는 @FunctionalInterface 애너테이션 붙이기 → 올바로 작성했는가 확인 해 줌
@FunctionalInterface
interface MyFunction {
public abstract int max(int a, int b);
}
// 구현하면?
// 익명 클래스이지만 위에 함수형 인터페이스 생성 했기 때문에 Object 타입 아닌 MyFunction 타입
MyFunction f = new MyFunction() { // new 조상 이름(클래스나 인터페이스) { 멤버 }
public int max(int a, int b) {
return a > b; a : b;
}
};
// 호출하면?
int value = f.max(3, 5) // OK, f에도 max()있고, MyFunction(리모콘)에 max() 있으니까
// int value = obj.max(3, 5) // ERROR, obj에 max() 있지만 Object(리모콘)에는 max() 없어서
▶ 함수형 인터페이스의 타입의 참조변수로 람다식 참조 가능
▷ 단, 함수형 인터페이스의 메서드와
▷ 람다식의 매개변수 개수와 반환타입이 일치해야 함
MyFunction f = (a, b) -> a > b ? a : b;
// 위 람다식과 같은 것
MyFunction f = new MyFunction() { // new 조상 이름(클래스나 인터페이스) { 멤버 }
public int max(int a, int b) {
return a > b; a : b;
}
};
int value = f.max(3, 5); // 실제로는 람다식(익명 함수)이 호출
▶ 실습
▷ 함수형 인터페이스 생성
▷ 익명 객체 생성
MyFunction function = new MyFunction() {
@Override
public int max(int a, int b) { // public : 오버라이딩 시, 접근제어자는 좁게 못바꿈 int max니까 default 보다 커야함
return a > b ? a : b;
}
};
▷ 람다식(익명 객체) 생성
▷ 익명 객체로 생성할 때보다 람다식 코드가 훨씬 간결
// 람다식을 다루기 위한 참조 변수의 타입은 함수형 인터페이스
MyFunction f = (a, b) -> a > b ? a : b
▷ 호출
package baek;
class Play3 {
public static void main(String[] args) {
MyFunction f = (a, b) -> a > b ? a : b;
int value = f.max(3, 5);
System.out.println("value : " + value);
}
}
@FunctionalInterface
interface MyFunction {
int max(int a, int b);
}
// console
value : 5
▷ 람다식과 함수형 인터페이스
▶ 함수형 인터페이스를 사용한 예
▷ sort
List<String> list = Arrays.asList("abc", "aaa", "bbb", "ccc", "ddd");
Collections.sort(list, new Comparator<String>() {
public int compare(String s1, String s2) {
return s2.compareTo(s1);
}
});
// ↓↓↓↓ 익명 객체'new Comparator<String>()'를 람다식으로 대체 ↓↓↓↓
@FunctionalInterface
interface comparator<T> {
int compare(T o1, T o2);
}
List<String> list = Arrays.asList("abc", "aaa", "bbb", "ccc", "ddd");
Collections.sort(list, (s1, s2) -> s2.compareTo(s1));
// sort가 받는 것
sort(List list, Comparator c)
// Comparator c에 람다식 'list, (s1, s2) -> s2.compareTo(s1)'을 넣은 것
Comparator c = (s1, s2) -> s2.compareTo(s1);
// Comparater c를 람다식이 참조 변수로 사용?
// Comparater c도 함수형 인터페이스 였던 것
Ch14 - 6. 함수형 인터페이스 타입 매개변수, 반환타입
▶ 함수형 인터페이스 타입의 매개변수
▷ 람다식을 매개변수로 넣어 호출
@FunctionalInterface
interface MyFunction {
void myMethod();
}
void aMethod(MyFunction f) {
f.myMethod(); // MyFunction에 정의 된 메서드 호출, 람다식 사용하려고 이름 붙여 둔 메서드
}
// aMethod에 람다식 넣어서 호출하는 법
MyFunction f = () -> System.out.println("myMethod()");
aMethod(f);
// ↓↓↓↓ 한 줄로 줄이면? ↓↓↓↓
aMethod( () -> System.out.println("myMethod()"));
▶ 함수형 인터페이스 타입의 반환타입
▷ 람다식을 반환하는 메서드
MyFunction myMethod() {
MyFunction f = () -> {};
return f;
}
// ↓↓↓↓ 한 줄로 줄이면? ↓↓↓↓
MyFunction myMethod() {
return () -> {};
}
▶ 예시
▷ 함수형 인터페이스 생성
▷ 이름이 run()인 메서드
@FunctionalInterface
interface MyFunction {
void run(); // public abstract void run();
}
▷ 매개변수의 타입이 MyFunction(함수형 인터페이스)인 메서드 생성
static void execute(MyFunction f) {
f.run();
}
▷ 반환 타입이 MyFunction인 메서드 생성
static MyFunction getMyFunction() {
MyFunction f = () -> System.out.println("f3.run()");
return f;
}
// ↓↓↓↓ 한 줄로 줄이면? ↓↓↓↓
static MyFunction getMyFunction() {
return () -> System.out.println("f3.run()");
}
▷ 람다식으로 MyFunction의 run()을 구현
public static void main(String[] args) {
MyFunction f1 = ()-> System.out.println("f1.run()");
}
▷ 익명 클래스로 MyFunction의 run()을 구현
public static void main(String[] args) {
MyFunction f2 = new MyFunction() {
public void run() { // public을 반드시 붙여야 함
System.out.println("f2.run()");
}
};
▷ getMyFunction() f3에 넣어 놓기
public static void main(String[] args) {
MyFunction f3 = getMyFunction();
▷ 전체
@FunctionalInterface
interface MyFunction {
void run(); // public abstract void run();
}
class Ex14_1 {
static void execute(MyFunction f) { // 매개변수의 타입이 MyFunction인 메서드
f.run();
}
static MyFunction getMyFunction() { //
MyFunction f = () -> System.out.println("f3.run()");
return f;
}
public static void main(String[] args) {
// 람다식으로 MyFunction의 run()을 구현
MyFunction f1 = ()-> System.out.println("f1.run()");
MyFunction f2 = new MyFunction() { // 익명클래스로 run()을 구현
public void run() { // public을 반드시 붙여야 함
System.out.println("f2.run()");
}
};
MyFunction f3 = getMyFunction();
f1.run();
f2.run();
f3.run();
execute(f1);
execute(()-> System.out.println("run()"));
}
}
// console
f1.run()
f2.run()
f3.run()
f1.run()
run()