PHpullh
학습 라이브러리/Java/메서드 참조 & 커스텀 함수형 인터페이스

JAVA · 람다/메서드

메서드 참조 & 커스텀 함수형 인터페이스

:: 연산자로 메서드를 람다처럼 사용하고 커스텀 함수형 인터페이스를 정의합니다.

람다/메서드중급method-reference::@FunctionalInterfaceconstructor-referenceThrowingSupplier

핵심 설명

:: 연산자로 메서드를 람다처럼 사용하고 커스텀 함수형 인터페이스를 정의합니다.

Java code

import java.util.*;
import java.util.function.*;

public class MethodRefs {

    // @FunctionalInterface — 단 하나의 추상 메서드
    @FunctionalInterface
    interface Transformer<T> {
        T transform(T input);
        default Transformer<T> andThen(Transformer<T> next) {
            return input -> next.transform(this.transform(input));
        }
    }

    @FunctionalInterface
    interface ThrowingSupplier<T> {
        T get() throws Exception;

        static <T> Supplier<T> wrap(ThrowingSupplier<T> s) {
            return () -> {
                try { return s.get(); }
                catch (Exception e) { throw new RuntimeException(e); }
            };
        }
    }

    static int doubleIt(int n) { return n * 2; }

    public static void main(String[] args) {
        var nums = List.of(1, 2, 3, 4, 5);

        // 정적 메서드 참조
        Function<Integer, Integer> dbl = MethodRefs::doubleIt;

        // 인스턴스 메서드 참조 (특정 객체)
        String prefix = "Hello";
        Predicate<String> startsWith = prefix::startsWith;

        // 인스턴스 메서드 참조 (임의 객체)
        Function<String, String> toUpper = String::toUpperCase;
        Function<String, Integer> length = String::length;

        // 생성자 참조
        Function<String, StringBuilder> sbFactory = StringBuilder::new;
        BiFunction<Integer, Integer, int[]> arrFactory = int[]::new;

        // 커스텀 함수형 인터페이스 사용
        Transformer<String> trim  = String::trim;
        Transformer<String> upper = String::toUpperCase;
        Transformer<String> pipeline = trim.andThen(upper);
        System.out.println(pipeline.transform("  hello  ")); // HELLO

        // ThrowingSupplier — checked exception 래핑
        Supplier<Properties> props = ThrowingSupplier.wrap(() -> {
            var p = new Properties();
            p.setProperty("key", "value");
            return p;
        });
        System.out.println(props.get().getProperty("key"));

        // 실용 예시
        nums.stream()
            .map(MethodRefs::doubleIt)
            .map(String::valueOf)
            .forEach(System.out::println);
    }
}

학습 팁

::로 참조하는 메서드의 시그니처가 함수형 인터페이스와 호환되어야 합니다. 컴파일러가 자동으로 매핑합니다.

주의할 점

인스턴스 메서드 참조(String::length)와 특정 객체 메서드 참조(str::length)는 함수 타입이 다릅니다. 전자는 Function, 후자는 Supplier입니다.

자주 묻는 질문

메서드 참조 & 커스텀 함수형 인터페이스란 무엇인가요?

:: 연산자로 메서드를 람다처럼 사용하고 커스텀 함수형 인터페이스를 정의합니다.

메서드 참조 & 커스텀 함수형 인터페이스 학습 시 주의할 점은 무엇인가요?

인스턴스 메서드 참조( String::length )와 특정 객체 메서드 참조( str::length )는 함수 타입이 다릅니다. 전자는 Function , 후자는 Supplier 입니다.