본문 바로가기
Computer Sience/Java

[JAVA8] 자바에서 제공하는 함수형 인터페이스

by 제우제우 2024. 9. 30.

목차 

  • 함수형 인터페이스 소개 
  • 참고 자료 
  • Function<T, R> 인터페이스 
  • 람다 표현식 간소화 조건 
  • BiFunction<T, U, R> 인터페이스 
  • Consumer<T> 인터페이스 
  • Supplier<T> 인터페이스 
  • Predicate<T> 인터페이스 

함수형 인터페이스? 

https://20240228.tistory.com/295

 

[JAVA8] 함수형 인터페이스와 람다 표현식 + 자바 함수형 프로그래밍

목차 함수형 인터페이스란?람다 표현식?람다 표현식 - 메소드 매개변수 활용 람다 표현식 - 변수로 저장 람다 표현식 - 리턴 타입 활용 자바에서 함수형 프로그래밍 / 일급 객체 함

20240228.tistory.com


Function<T, R> 인터페이스 

Plus10 클래스 implemets Function 인터페이스 

/**
 * Function<T, R> 함수형 인터페이스 T: 매개 변수 R: 반환 타입
 * java.util.function 패키지
 */
public class Plus10 implements Function<Integer, Integer> {
    @Override
    public Integer apply(Integer integer) {
        return integer + 10;
    }
}

 

Plus10 사용해서 출력하기 

public class Main {
    public static void main(String[] args) {
        Plus10 plus10 = new Plus10();
        System.out.println(plus10.apply(10));
    }
}

 

Function 함수 람다 표현식1

public class Main {
    public static void main(String[] args) {
        Plus10 plus10_class = new Plus10();

        System.out.println(plus10_class.apply(10)); // 10

        // 람다 표현식을 통한 Function 함수 일급 객체화
        Function<Integer, Integer> plus10_first_class_object = (input) -> {
            return input + 10;
        };
        System.out.println(plus10_first_class_object.apply(10)); // 10
    }
}


Function 함수 람다 표현식2

public class Main {
    public static void main(String[] args) {
        // 람다 표현식을 통한 Function 함수 일급 객체화
        Function<Integer, Integer> plus10_first_class_object = (input) -> input + 10;
        System.out.println(plus10_first_class_object.apply(10)); // 10
    }
}

 

compose

default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
    Objects.requireNonNull(before);
    return (V v) -> apply(before.apply(v));
}

 

Function 인터페이스의 default 메서드이다. 

 

compose() 활용 

public class Main {
    public static void main(String[] args) {
        Function<Integer, Integer> plus10 = i -> i + 10;
        Function<Integer, Integer> multiply2 = i -> i * 2;
        
        /**
         * 고차 함수의 성격을 가짐 함수가 함수를 매개변수로 받을 수 있고 함수를 리턴할 수도 있다.  
         */
        Function<Integer, Integer> multiply2BeforePlus10 = plus10.compose(multiply2);
        System.out.println(multiply2BeforePlus10.apply(20)); // 20 * 2 + 10 -> 50
    }
}

 

andThen

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
    Objects.requireNonNull(after);
    return (T t) -> after.apply(apply(t));
}

 

andThen 활용 

public class Main {
    public static void main(String[] args) {
        Function<Integer, Integer> plus10 = i -> i + 10;
        Function<Integer, Integer> multiply2 = i -> i * 2;

        System.out.println(plus10.andThen(multiply2).apply(5)); // (5 + 10) * 2 -> 30
    }
}

람다 표현식 간소화 조건 

단일 매개변수

람다 표현식의 매개변수가 하나인 경우, 괄호를 생략할 수 있다.

 Function<Integer, Integer> plus10 = (i) -> i + 10;
 
 // 간소화 - 매개변수가 하나인 경우, 괄호를 생략
 Function<Integer, Integer> plus10 = i -> i + 10;

 

단일 표현식

람다 표현식의 본체가 단일 표현식인 경우, 중괄호 {}와 return 키워드를 생략할 수 있다.

 Function<Integer, Integer> plus10 = (i) -> {
 	return i + 10;
 };
 
 // 간소화 - 단일 표현식
  Function<Integer, Integer> plus10 = i -> i + 10;

BiFunction<T, U, R> 인터페이스 

Function 인터페이스와 거의 동일하다. 

두 개의 값(T, U)를 받아서 R 타입을 리턴하는 함수 인터페이스

@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));
    }
}

 

활용 

public class Main {
    public static void main(String[] args) {
        //BiFunction<T, U, R> 사용
        BiFunction<Integer, Integer, Integer> biFunction = (a, b) -> {
            return a + b;
        };
        System.out.println(biFunction.apply(10, 21)); // 10 + 21 -> 31
    }
}

Consumer<T> 인터페이스 

T 타입을 받아서 아무값도 리턴하지 않는 함수 인터페이스

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
    
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

 

Consumer 활용 

// Consumer<T>
Consumer<String> printStr = s -> System.out.println(s);
printStr.accept("안녕"); // "안녕" 출력

Supplier<T> 인터페이스

T 타입의 값을 제공하는 함수 인터페이스

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

 

Supplier 활용 

// Supplier<T> 
Supplier<Integer> get10 = () -> 10;
System.out.println(get10.get()); // 10 출력

Predicate<T> 인터페이스 

T 타입을 받아서 boolean을 리턴하는 함수 인터페이스

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
    // 생략 ...
}

 

함수 조합용 메소드 존재

  • And
  • Or
  • Negate

Predicate 활용 

// Predicate<T>
Predicate<String> startsWithA = s -> s.startsWith("A");
System.out.println(startsWithA.test("ABC")); // true
System.out.println(startsWithA.test("BAC")); // false

참고 자료 

인프런 백기선님 더 자바, Java 8

 

더 자바, Java 8 강의 | 백기선 - 인프런

백기선 | 자바 8에 추가된 기능들은 자바가 제공하는 API는 물론이고 스프링 같은 제 3의 라이브러리 및 프레임워크에서도 널리 사용되고 있습니다. 이 시대의 자바 개발자라면 반드시 알아야 합

www.inflearn.com

 

Java8 함수형 인터페이스 공식 문서

 

Java Platform SE 8

 

docs.oracle.com

정리한 인터페이스 말고도 많은 함수형 인터페이스가 존재한다. 

다른 인터페이스들은 공식 문서를 참고하자.