[Java 8] 4. Function & BiFunction

seony·2023년 4월 24일

java8

목록 보기
4/16

⭐️ 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"));

        // andthen은 앞에서부터 순서대로
        System.out.println("Result of andthen is : " + function.andThen(addSomeString).apply("java8"));

        // compose 인자에 전달된 것을 먼저
        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을 만든다.

0개의 댓글