2024.06.05.WED <D + 16> 함수형 인터페이스
A. 함수형 인터페이스
타입 f = (a,b) -> a > b ? a : b ; //함수 형태 new Object() { //익명 클래스
int (int a, int b) {
return a > b ? a : b ;
}
}
타입 f = (a,b) -> a > b ? a : b;
MyFunc f = (a,b) -> a > b ? a : b;
@FunctionalInterface
@FunctionalInterface 사용시 함수형 인터페이스가 올바르게 정의가 되었는지를 확인 가능.
interface MyFunc {
public abstract int max(int a, int b);
}
MyFunc f = new MyFunc() { // 인터페이스를 구현한 익명클래스
// MyFunc 인터페이스의 추상메소드인 max를 구현
public int max(int a, int b) {
return (a,b) -> a > b ? a : b;
}
};
사용시 int big = f.max(3,5); //익명 객체의 메소드 호출
결론) 람다식을 어떤 메소드의 매개변수로 전달이 가능해지고,
MyFunc 인터페이스는 람다식을 다루기 위한 인터페이스가 되고, 이를 "함수형 인터페이스" 라고 함.
// 함수형 인터페이스 생성하기
@FunctionalInterface
interface MyFunc {
public abstract void run(); //추상메소드임
}
public class LambdaEx1 {
// 메인에서 사용해야 하니 static 으로 작성
// 함수형 인터페이스를 매개변수로 활용하는 메소드 생성하기
static void execute(MyFunc f) {
f.run();
}
// 함수형 인터페이를 반환형으로 하는 메소드 생성하기
static MyFunc getMyFunc() {
MyFunc f = () -> System.out.println("f3.run()"); //f를 의미
return f;
}
public static void main(String[] args) {
// case1. 함수형 인터페이스로 람다식 선언하기.
MyFunc f1 = () -> System.out.println("f1. run()");
// case2. 익명클래스 형태의 함수형 인터페이스 구현하기.
MyFunc f2 = new MyFunc() {
// 함수형 인터페이스의 추상메소드를 구현.
@Override
public void run() {
System.out.println("f2. run()");
}
};
// case3. getMyFunc() 사용하기
MyFunc f3 = getMyFunc();
// case4. 매개변수 execute() 사용하기.
// case4.1. 함수형 인터페이스를 매개변수로 전달하는 방법
execute(f1);
// case4.2. 함수형 인터페이스 없이 직접 람다식으로 전달하는 방법
execute(() -> System.out.println("run"));
f1.run();
f2.run();
f3.run();
}
}
B. 함수형 인터페이스의 JAVA API
JAVA API의 사용 목적
1. Stream의 API문서를 보고 사용하기 위함.
-> Stream의 메소드를 사용해야 하는데, 이때 각 메소드의 매개변수를 이해하고 사용하기 위함.
B-1. 매개변수가 없거나 하나인 함수형 인터페이스 (종류 및 의미를 이해!)
a. Supplier - 매개변수는 없고 반환값만 있음.
b. Consumer - 매개변수만 있고 반환값이 없음.
c. Function<T, R> - 일반적인 함수. 하나의 매개변수를 받아 처리 후, 결과를 반환.
d. Predicate - 조건식을 표현할 때 사용함. 매개변수는 하나, 반환타입이 boolean.
B-2. 매개변수가 두개인 함수형 인터페이스 (종류 및 의미를 이해!)
a. BiConsumer<T, U> - 2개의 매개변수가 있고 반환값이 없음.
b. BiFunction<T, U, R> - 일반적인 함수. 두개의 매개변수를 받아 처리 후, 결과를 반환.
c. BiPredicate<T, U> - 조건식을 표현할 때 사용함. 매개변수는 두개, 반환타입이 boolean.
B-3. Operator
a. UnaryOperator (Unary: 단항)
UnaryOPerator
-> 매개변수가 하나이고, 매개변수와 결과값의 타입이 동일한 경우.
Function와 동일, 차이점은 매개변수와 결과의 타입이 동일한 것.
b. BinaryOperator (Binary: 이항)
-> 매개변수가 두개이고, 매개변수와 결과의 타입이 동일한 경우.
BiFunction와 동일, 차이점은 매개변수와 결과의 타입이 동일한 것.
B-4. 함수형 API가 매개변수로 사용되는 JAVA API메소드.
B-5. 반복문 돌리기
public class LambdaEx2 {
public static void main(String[] args) {
// 데이터 소스 (ArrayList) => Collection(List, Set, Map (Collection의 인터페이스 종류))
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++)
{ list.add(i); }
// forEach
// forEach의 함수형 인터페이스 : Consumer<? super E> action
// 매개변수가 있고 반환값이 없음.
list.forEach(i -> System.out.println(i + ", "));
System.out.println();
// removeIf()
// 함수형 인터페이스 : Predicate<? super E> filter
list.removeIf(i -> i % 2 == 0);
System.out.println(list);
// replaceAll
// 함수형 인터페이스 : UnaryOperator<E> operator
// Function<T> 와 차이점 : 매개변수 타입과 반환 타입이 동일한 점.
list.replaceAll(i -> i * 10);
// Map 생성하기 (데이터 소스)
Map<String, String> map = new HashMap<String, String>();
map.put("1", "1");
map.put("2", "2");
map.put("3", "3");
map.put("4", "4");
// forEach()
// 함수형 인터페이스 : BiConsumer<? super K, ? super V> action
// 매개변수가 두 개 이고, 반환값이 없는 경우.
// (K, V) -> System.out.println("{" + k + ", " + v + "}")
map.forEach((k,v) ->System.out.println( "{" + k + ", " + v + "}"));
System.out.println();
}
}