[ch.03] JDK 함수형 인터페이스

2024. 5. 16. 20:54·함수형 프로그래밍

1. 자바 함수형 인터페이스

  • Function : 인수를 받고 결과를 반환 한다.
  • Consumer : 인수만 받고 결과는 반환 하지 않는다.
  • Supplier : 인수를 받지 않고 결과만 반환 한다.
  • Predicate : 인수를 받아서 표현식에 대해 테스트하고 boolean 값을 결과로 반환 한다.

Function

  • 하나의 입력과 출력을 가진 전통적인 함수
  • 단일 추상 메서드는 apply 로 T 타입의 인수를 받아 R 타입의 결과를 생성한다.
@FunctionalInterface
public interface Function<T, R> {
  R apply(T t);
}

 

문자열을 정수로 변환하거나 객체의 속성을 추출

Function<String, Integer> strLength = str -> str != null ? str.length() : 0;

Integer length = strLength.apply("fucking hard"); 
System.out.println(length); // 12

 

하나의 데이터 형식을 다른 데이터 형식으로 매핑

Function<String, String> toUpperCase = String::toUpperCase;

List<String> names = List.of("park", "seong", "hyeon");
List<String> upperNames = 
        names.stream()
                .map(toUpperCase)
                .collect(Collectors.toList());
System.out.println(names); // park seong hyeon
System.out.println(upperNames); // PARL SEONG HYEON

 

여러 함수를 연속적으로 실행하여 데이터 변환 작업 수행 가능

Function<String, String> toUpperCase2 = String::toUpperCase;
Function<String, String> removeWhiteSpace = String::trim;

Function<String, String> pipeline = toUpperCase2.andThen(removeWhiteSpace);

String result = pipeline.apply(" hello ");
System.out.println(result); // 공백 없는 hello

 

Consumer

  • 입력 파라미터를 소비하지만 아무것도 반환하지 않는다.
@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

public static void main(String[] args){
    // 일반적인 void 메서드
    void println(String str){
        System.out.println(str);
    }
    println("Hello");

    // Consumner 사용
    Consumer<String> println = str -> System.out.println(str);
    println.accept("Hello");
}

 

Supplier

  • Consumer의 반대이며, 어떠한 입력 파라미터도 받지 않지만 단일값을 반환한다.
  • Supplier는 지연실행에 사용된다.
@FunctionalInterface
public interface Supplier<T> {
    T get();
}

Supplier<Integer> randomIntegerSupplier = () -> (int) (Math.random() * 100);
Integer randomNumber = randomIntegerSupplier.get();
System.out.println(randomNumber); // 랜덤 숫자 출력
지연 실행 Deferred execution
  • 코드 블록이나 함수를 나중에 필요한 시점에 실행되도록 하는 프로그래밍 패턴
  • 비용이 많이 드는 작업을 Supplier로 래핑하고 필요할 때만 get을 호출
  • 예를 들어, DB 조회시 연결이나 쿼리 실행은 비용이 크고 시간이 걸리는 작업이다. 프로그램이 시작될 때보다 실제로 데이터가 필요한 시점에 DB 연결을 수행하는 것이 효율적이다.

 

Predicate

  • 단일 인수를 받아 참인지 거짓인지 평가한다.
  • 보통 조건문에서 사용되나 컬렉션의 요소를 필터링할 때 유용하다.
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

    // 짝수 필터링 정의
    Predicate<Integer> isEven = num -> num % 2 == 0;

    // 필터링 결과 출력
    numbers.stream()
            .filter(isEven)
            .forEach(num -> System.out.println(num + " "));
}

2. 함수 합성

글루 메서드 (glu method) : 여러 가지 요소를 서로 연결하거나 결합하는 역할을 하는 메서드
  • 함수 함성으로 작은 함수들을 결합하여 복잡한 작업을 처리할 수 있다.
  • 자바에서는 글루 메서드를 사용하는 데 글루 메서드는 기본적으로 함수형 인터페이스 자체에 직접 구현된다.
  • 결합된 기능을 가진 새로운 인터페이스를 반환함으로써 두 함수형 인터페이스 사이의 연결고리를 만든다.
default <V> Function<V, R> compose(Function<? super V, ? extends T> before)
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after)

// compose
Function<Integer, Integer> func = num -> num + num;
Function<Integer, Integer> composeFunc = num -> num * num;
    
// composeFunc이 먼저 실행된 후, func 실행
Integer apply = func.compose(composeFunc).apply(5);
System.out.println(apply); // 5 * 5 -> 25 + 25 -> 50

// andThen
Function<Integer, Integer> func = num -> num + num;
Function<Integer, Integer> andThenFunc = num -> num * num;

// func이 먼저 실행된 후, andThenFunc 실행
Integer apply = func.andThen(andThenFunc).apply(5);
System.out.println(apply); // 5 + 5 -> 10 * 10 -> 100

3. 함수 지원 확장

  • 기존 타입을 더 함수적으로 만들기 위해 인터페이스에 기본 메서드 추가
  • 공통 함수형 작업을 제공하기 위해 정적 헬퍼를 생성한다.

기본 메서드

  • 인터페이스에 새로운 기능을 추가할 때마다 모든 구현에 새로운 메서드를 구현해야 한다.
  • 프로젝트 크기가 큰 경우, 라이브러리 코드의 경우 모든 구현을 업데이트 하는 것은 쉽지 않다.
  • 이러한 상황에 기본 메서드를 사용한다.
// Collection의 구현 클래스에 stream 기능을 사용하여
// 함수적으로 코드를 작성할 수 있다.
public interface Collection<E> extends Iterable<E> {
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }

    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}
public class StreamEx {

    public static void main(String[] args) {

        List<Member> members = createMember();

        members.stream()
                .filter(member -> member.nameLength())
                .map(member -> member.getName())
                .map(name -> name.toUpperCase())
                .forEach(name -> System.out.println(name));

        // 출력
        // STEVE
        // KENNY
        // MARIA
    }

    static List<Member> createMember() {
        return Arrays.asList(
                new Member("john"),
                new Member("steve"),
                new Member("dave"),
                new Member("kenny"),
                new Member("maria")
        );
    }

    static class Member {
        String name;

        public Member(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        boolean nameLength() {
            return this.name.length() >= 5;
        }
    }
}

 

정적 헬퍼

  • 정적 멤버로 구현된 유틸리티 메서드나 상수를 가지고 있다.
  • 여러 곳에서 공통적으로 사용되는 기능이나 상수를 제공한다.
  • 함수형 인터페이스와 정적 헬퍼 메서드를 조합하여 다양성을 확장할 수 있다.
public class PredicateUtils {
	// null이 아닌지 확인하는 Predicate
    public static <T> Predicate<T> isNotNull() {
    	return t -> t != null;
    }

    // 주어진 문자열이 비어있지 않은지 확인하는 Predicate
    public static Predicate<String> isNotEmptyString() {
        return s -> s != null && !s.isEmpty();
    }
}

 

저작자표시 (새창열림)

'함수형 프로그래밍' 카테고리의 다른 글

[ch.06] 스트림을 이용한 데이터 처리  (0) 2024.06.06
[ch.05] 레코드  (0) 2024.06.01
[ch.04] 가변성 & 불변성  (0) 2024.05.23
[ch.02] 함수형 자바  (0) 2024.05.09
[ch.01] 함수형 프로그래밍 소개  (1) 2024.05.02
'함수형 프로그래밍' 카테고리의 다른 글
  • [ch.05] 레코드
  • [ch.04] 가변성 & 불변성
  • [ch.02] 함수형 자바
  • [ch.01] 함수형 프로그래밍 소개
tjdgus
tjdgus
  • tjdgus
    Do It...
    tjdgus
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Language
        • Java
      • CS
        • Data Structure
        • OS
        • Algorithm
        • Network
      • 오류 모음집
      • ETC
      • 함수형 프로그래밍
      • JPA
      • Toy
      • 데이터베이스
      • Spring
      • 코딩테스트
        • 99클럽 4기
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    개발자취업
    99클럽
    TiL
    티스토리챌린지
    항해99
    오블완
    코딩테스트준비
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
tjdgus
[ch.03] JDK 함수형 인터페이스
상단으로

티스토리툴바