⭐️ Function Interface
apply 추상 메서드를 구현하면 된다.
- 인자 하나를 받아 return 한다.
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
🌱 Function 사용 예시
package com.learnJava.functionalInterfaces;
import java.util.function.Function;
public class FunctionExample {
static Function<String, String> function = (name) -> name.toUpperCase();
static Function<String, String> addSomeString = (name) -> name.toUpperCase().concat("default");
public static void main(String[] args) {
System.out.println("Result is : " + function.apply("java8"));
System.out.println("Result of andthen is : " + function.andThen(addSomeString).apply("java8"));
System.out.println("Result of compose is : " + function.compose(addSomeString).apply("java8"));
}
}
andthen은 앞에서부터 순서대로 function을 실행한다.
compose는 인자부터 수행한다.
FunctionalInterface를 사용하면 아래와 같이 재사용성을 높일 수 있다.
package com.learnJava.functionalInterfaces;
public class FunctionExample1 {
public static String performConcat(String str) {
return FunctionExample.addSomeString.apply(str);
}
public static void main(String[] args) {
String result = performConcat("Hello");
System.out.println("Result : " + result);
}
}
🌱 Function Student 예시
Map으로 학생 이름과 학점을 매핑한다.
- 인자로
List<Student> 를 받아서 Map을 반환한다.
package com.learnJava.functionalInterfaces;
import com.learnJava.data.Student;
import com.learnJava.data.StudentDataBase;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
public class FunctionStudentExample {
static Function<List<Student>, Map<String, Double>> studentFunction = (students) -> {
Map<String, Double> studentGradeMap = new HashMap<>();
students.forEach(student -> {
if (PredicateStudentExample.p1.test(student))
studentGradeMap.put(student.getName(), student.getGpa());
});
return studentGradeMap;
};
public static void main(String[] args) {
System.out.println(studentFunction.apply(StudentDataBase.getAllStudents()));
}
}
⭐️ BiFunction Interface
Function 인터페이스와 달리 compose가 존재하지 않는다.
- 인자 2개를 받는다.
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u) -> after.apply(apply(t, u));
}
}
🌱 BiFunction 사용
package com.learnJava.functionalInterfaces;
import com.learnJava.data.Student;
import com.learnJava.data.StudentDataBase;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Predicate;
public class BiFunctionExample {
static BiFunction<List<Student>, Predicate<Student>, Map<String, Double>> biFunction = (students, studentPredicate) -> {
Map<String, Double> studentGradeMap = new HashMap<>();
students.forEach(student -> {
if (studentPredicate.test(student)) {
studentGradeMap.put(student.getName(), student.getGpa());
}
});
return studentGradeMap;
};
public static void main(String[] args) {
System.out.println(biFunction.apply(StudentDataBase.getAllStudents(), PredicateStudentExample.p1));
}
}
- 인자 1:
List<Student>
- 인자 2:
Predicate<Student>
➜ Predicate 를 사용하여 필터링해서 학생 Map을 만든다.