[Java] 함수형 인터페이스(functional interface)

애이용·2021년 5월 2일
0

Java

목록 보기
6/8
post-thumbnail

(자바 8에서 추가된 것은 람다와 스트림이다.)

자바 8(JDK 1.8)부터 제공
java.util.function 패키지
오로지 람다식만을 지원하기 위해 만들어진 인터페이스 모음
람다식 타겟 타입 = 표준 API 함수적 인터페이스 + 사용자 정의 인터페이스

Functional Interface

함수를 일급 객체로 사용할 수 없는 자바 언어의 단점을 보완하기 위해 도입되었다.
덕분에 자바는 전보다 간결한 표현이 가능해졌고, 가독성이 높아졌다.
Functional Interface는 일반적으로 구현해야 할 추상 메서드가 하나만 정의된 인터페이스를 뜻한다.

  • 함수를 일급 객체(First class object)로 사용
    FuncInterface funcInterface1 = () -> System.out.println("test");
  • 추상 메서드를 딱 하나만 가지고 있는 인터페이스
  • SAM(Single Abstract Method) 인터페이스
  • @FunctionalInterface 어노테이션을 가지고 있는 인터페이스

예를 들자.

@FunctionalInterface
public interface FuncInterface {
    void test();

//    void test2(); // 에러

    static void printStatic(){
        System.out.println("static");
    }

    default void printDefault(){
        System.out.println("default");
    }
}

static 메서드와 default 메서드는 함수형 인터페이스를 만드는 데 상관이 없다.
void test2(); 이 추상메서드를 하나 더 정의하면 에러가 발생한다.
Invalid '@FunctionalInterface' annotation

메인 메서드를 살펴보자.

// 기존 방법 : 익명 내부 클래스를 만들어 사용
FuncInterface funcInterface = new FuncInterface() {
    @Override
    public void test() {
    	System.out.println("test");
    }
};

// 자바 8 이후의 방법 : 람다표현식 이용
FuncInterface funcInterface1 = () -> System.out.println("test");

FuncInterface funcInterface2 = () -> {
	System.out.println("test");
    System.out.println("test2");
};

람다 표현식

  • 함수형 인터페이스의 인스턴스를 만드는 방법으로 사용될 수 있다.
  • 코드 길이가 줄어듬
  • 메서드 매개변수, 리턴타입, 변수로 만들어 사용 가능

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

java.util.function 패키지

인터페이스매개변수리턴값설명
ConsumerOX추상메서드 제공
SupplierXO
FunctionOO주로 매개변수를 반환값 타입으로 변환 후 반환
OperatorOO주로 매개변수를 연산 후 결과값 반환 역할
PredicateOO주로 매개변수를 조사한 후 논리값 반환 역할

✔ Consumer< T >

인터페이스매개변수리턴값설명
ConsumerOX추상메서드 제공
  • accept(T t) 메서드를 제공하는 함수형 인터페이스
  • 매개변수를 받아 소비하는 일을 구현
  • 다양한 오버로딩 지원
@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

1개의 매개변수

        Consumer<Integer> c = count -> {
            for (int i = 0; i < count; i++)
                System.out.println(i);
        };
        c.accept(10);

출력결과

0
1
2
3
4
5
6
7
8
9

2개의 매개변수

BiConsumer<String, Integer> info = (name, age) -> {
	System.out.println("이름: " + name);
    System.out.println("나이: " + age);
};
info.accept("문아영", 22);

출력결과

이름: 문아영
나이: 22

✔ Supplier< R >

인터페이스매개변수리턴값
SupplierXO
  • get() 메서드를 제공하는 함수형 인터페이스
  • T 타입의 값을 제공하는 함수형 인터페이스
  • 데이터 공급 역할
Supplier<Integer> get22 = () -> 22;
System.out.println(get22.get());

✔ Function< T, R >

인터페이스매개변수리턴값설명
FunctionOO주로 매개변수를 반환값 타입으로 변환 후 반환
  • R apply(T t) 메서드를 제공하는 함수형 인터페이스
  • T 타입을 받아서 R 타입을 반환하는 함수형 인터페이스
Function<Integer, Integer> plus22 = i -> i + 22;
System.out.println(plus22.apply(1)); //23
  • Student 클래스를 생성해보자
public class Student {

    private String name;

    private int kor;

    private int math;

    private int eng;

    public Student(String name, int kor, int math, int eng) {
        this.name = name;
        this.kor = kor;
        this.math = math;
        this.eng = eng;
    }

    public Student() {}

    public String getName() {
        return name;
    }

    public int getKor() {
        return kor;
    }

    public int getMath() {
        return math;
    }

    public int getEng() {
        return eng;
    }
}

메인 메서드를 작성해보자

Function<Student, Integer> sum = student1 -> student1.getEng() + student1.getMath() + student1.getKor();
Student student = new Student("문아영", 90, 100, 95);

System.out.println(student.getName() + " 학생의 총점은 " + sum.apply(student) + "점입니다.");
문아영 학생의 총점은 285점입니다.

✔ Operator

인터페이스매개변수리턴값설명
OperatorOO주로 매개변수를 연산 후 결과값 반환 역할
  • 매개변수와 반환값이 있는 메서드를 제공하는 함수형 인터페이스
  • Function의 하위 호환 인터페이스(서브셋)
  • 주로 매개값을 연산을 통해 결과값을 만들어내고 그 값을 반환한다.
  • Function과 큰 차이는 Operator는 매개값과 반환값의 타입이 동일하다.
    (=> 연산자의 특징)

BinaryOperator< T >

BinaryOperator<Integer> binaryOperator = (n1, n2) -> n1 + n2;
// BinaryOperator<Integer> binaryOperator2 = Integer::sum; // 같은 표현
System.out.println(binaryOperator.apply(8, 2)); // 10

UnaryOperator< T >

  • Function<T, R>의 특수한 형태로 입력값 하나를 받아 동일한 타입을 리턴하는 함수 인터페이스
UnaryOperator<Integer> plus20 = (i) -> i + 20;
UnaryOperator<Integer> multiply2 = (i) -> i * 2;
System.out.println(plus20.apply(10)); // 30
System.out.println(multiply2.apply(10)); // 20
System.out.println(plus20.andThen(multiply2).apply(10)); // 60

✔ Predicate

인터페이스매개변수리턴값설명
PredicateOO주로 매개변수를 조사한 후 논리값 반환 역할
  • test(T t) 메서드를 제공하는 함수형 인터페이스
  • T 타입을 받아서 boolean을 리턴하는 함수형 인터페이스
Predicate<Integer> p = n -> n > 0;

System.out.println(p.test(-5)); // false
profile
로그를 남기자 〰️

0개의 댓글