3 minute read

표준 함수적 인터페이스

  • 자바에서 제공되는 표준 API에서 한 개의 추상 메서들을 갖는 인터페이스는 람다식을 이용하여 익명 구현 객체로 표현 가능
    • ex) Runnable
  • 자바 8부터 자주 사용되는 함수적 인터페이스는 java.util.function 패키지로 제공
    • 이 패키지의 목적은 메서드 또는 생성자의 매개 타입으로 사용되어 람디식을 대입할 수 있도록 하는 것
    • 자바 8부터 추가되거나 변경된 API는 표준 함수적 인터페이스를 매개 타입으로 사용
  • 용도에 따라 분류
    • Consumer, Supplier, Fuction, Operator, Predicate

Consumer

  • 함수적 인터페이스
  • 리턴 값이 없는 accept() 메서드를 포함
  • accept() 메서드는 매개값을 소비하는 역할
    • 사용만 하고 리턴 값이 없음
  • Consumer : 한 개의 매개값(제네릭으로 지정된 타입)을 받아 소비
  • BiConsumer : 두 개의 매개값을 받아 소비
  • DoubleConsumer : 하나의 double 값을 받아 소비
  • ObjIntConsumer : 제네릭으로 지정된 타입과 int(정수)의 매개값을 받아 소비(2개)
public class A_Consumer {
	public void method1() {
        // Consumer
		Consumer<String> consumer = (String str) -> {
			System.out.println(str);
		};
        // 타입 생략 가능, 매개값이 하나일 경우 소괄호 생략 가능, 실행문이 하나일 경우 중괄호 생략 가능
		// Consuer<Strong> consumer = str -> System.out.println(str);
		consumer.accept("Consumer : 한 개의 매개값(제네릭으로 지정된 타입)을 받아 소비");
		
        // BiConsumer
		BiConsumer<String, String> biConsumer = (String str1, String str2) -> {
			System.out.println(str1 + str2);
		};
		biConsumer.accept("BiConsumer : ", "두 개의 매개값을 받아 소비");
		
        // DoubleConsumer
		DoubleConsumer dConsumer = (value) -> {
			System.out.println("DoubleConsumer : 하나의 double 값을 받아 소비. value:" + value);
		};
		dConsumer.accept(3.14);
		
        // ObjIntConsumer
		ObjIntConsumer<String> objIntConsumer = (String str, int i) -> {
			System.out.println(str + i);
		};
		objIntConsumer.accept("objIntConsumer : 제네릭으로 지정된 타입과 int(정수)의 매개값을 받아 소비(2개)", 10);
	}
}

Supplier

  • 함수적 인터페이스
  • 매개변수가 없고 리턴값이 있는 getXXX() 메서드 포함
  • 이 메서드는 실행 후 호출한 곳으로 데이터를 리턴(공급)하는 역할
package java.util.function;

@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

-

Supplier<String> supplier = () -> {
    return "Supplier : 제네릭으로 지정된 타입의 객체를 리턴"; // Supplier<String>
};
System.out.println(supplier.get()); // Supplier 인터페이스에 있는 get메서드 호출

// return값이 하나일 경우 return 키워드 생략 가능
// 실행문이 하나일 경우 중괄호 생략 가능
// Supplier<String> supplier = () -> "Supplier : 제네릭으로 지정된 타입의 객체를 리턴";

-

package java.util.function;

@FunctionalInterface
public interface IntSupplier {

    /**
     * Gets a result.
     *
     * @return a result
     */
    int getAsInt();
}

-

// 정수값 리턴
IntSupplier intSupplier = () -> {
    return 10 + 20;
};
System.out.println(intSupplier.getAsInt());

Function

  • 매개변수와 리턴값이 있는 applyXXX() 메서드 포함
  • 매개변수를 리턴값으로 매핑(타입 변환) 하는 역할
package com.kh.lambda.standard.model.vo;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
	private String name;
	private int age;
	private String gender;
	private int math;
	private int english;
}

-

public void method1() {
    Student student = new Student("홍길동", 10, "남자", 80, 70);

    // Student 객체를 받아서 String으로 타입 변환    
    Function<Student, String> function = s -> s.getName();
    System.out.println("이름: " + function.apply(student));
    
    System.out.print("수학 :");
    printInt((s) -> s.getMath(), student);
    
    System.out.print("영어 :");
    printInt((s) -> s.getEnglish(), student);
    
    System.out.print("평균 :");
    printInt((s) -> (s.getMath() + s.getEnglish()) / 2, student);
}

public void printInt(ToIntFunction<Student> function, Student student) {
    System.out.println(function.applyAsInt(student));
}

이거 쫌 뭔 말인지 모르겠는데..??
ToIntFunction 이거 갑자기 왜.. 왜 이렇게 헷갈려.
쌤이 ToIntFunction 아직 이거는 생각하지 말라고 하셨음.. 그래도 되나요.


Operator

  • 매개변수와 리턴값이 있는 applyXXX() 메서드 포함
  • 매개변수를 이용하여 연산하고 동일한 타입으로 결과 리턴
// IntBinaryOperator : 두 개의 정수
IntBinaryOperator IntBinaryOperator = (a, b) -> a * b;
System.out.println(IntBinaryOperator.applyAsInt(10, 20)); // 200

// IntUnaryOperator : 한 개의 정수
IntUnaryOperator IntUnaryOperator = (a) -> a * a;
System.out.println(IntUnaryOperator.applyAsInt(10)); // 100

Predicate

  • 매개변수와 boolean 리턴 값이 있는 testXXX() 메서드 포함
  • 이 메서드의 매개변수를 확인하여 true/false를 리턴하는 역할
Student student1 = new Student("아이유", 20, "여자", 100, 90);
Student student2 = new Student("유인나", 22, "여자", 80, 100);

Predicate<Student> predicate = student -> {
    return student.getGender().equals("남자");
};

System.out.println("아이유는 남자? : " + predicate.test(student1));

어떤 건 이해가 팍 되는데.. 어떤 건 너무 이해가 안 되고..
그런 것도 수업 이후에 다시보면 멘붕의 연속.


Categories:

Updated: