200===Dev Language/Java

Java의 함수형 인터페이스 완벽 가이드 🎯

블로글러 2024. 10. 30. 22:20

Java의 함수형 인터페이스(java.util.function)에 대해 알아보겠습니다.

함수형 인터페이스가 뭔가요? 🤔

쉽게 생각해볼까요?

  • 주방장에게 "양파 써세요" → Consumer (소비자)
  • 손님이 "메뉴 추천해주세요" → Supplier (공급자)
  • "이 음식이 매운가요?" → Predicate (판단자)
  • "이 음식을 매운맛으로 바꿔주세요" → Function (변환자)

자바에서 제공하는 대표적인 함수형 인터페이스들이 바로 이런 역할을 합니다!

주요 함수형 인터페이스 살펴보기 🎭

1. Consumer - 뭔가를 받아서 처리하기

Consumer<String> printer = message -> System.out.println(message);
printer.accept("안녕하세요!"); // 출력: 안녕하세요!

// 실제 활용 예시
List<String> names = Arrays.asList("김철수", "이영희", "박민수");
names.forEach(name -> System.out.println(name));

2. Supplier - 뭔가를 제공하기

Supplier<String> greeting = () -> "안녕하세요!";
String message = greeting.get(); // 결과: "안녕하세요!"

// 실제 활용 예시
Supplier<LocalDateTime> now = () -> LocalDateTime.now();
System.out.println("현재 시각: " + now.get());

3. Predicate - 조건 검사하기

Predicate<Integer> isPositive = num -> num > 0;
boolean result = isPositive.test(5); // 결과: true

// 실제 활용 예시
List<Integer> numbers = Arrays.asList(1, -2, 3, -4, 5);
List<Integer> positiveNumbers = numbers.stream()
    .filter(isPositive)
    .collect(Collectors.toList()); // 결과: [1, 3, 5]

4. Function<T,R> - 값을 변환하기

Function<String, Integer> stringToLength = str -> str.length();
int length = stringToLength.apply("Hello"); // 결과: 5

// 실제 활용 예시
List<String> words = Arrays.asList("apple", "banana", "cherry");
List<Integer> wordLengths = words.stream()
    .map(stringToLength)
    .collect(Collectors.toList()); // 결과: [5, 6, 6]

실전 활용 예시 💪

1. 주문 처리 시스템

public class OrderSystem {
    // 주문 검증
    Predicate<Order> isValidOrder = order -> 
        order.getAmount() > 0 && order.getCustomerId() != null;

    // 주문 처리
    Consumer<Order> processOrder = order -> {
        System.out.println("주문 처리 중: " + order.getId());
        // 실제 처리 로직...
    };

    // 주문 ID 생성
    Supplier<String> orderIdGenerator = () ->
        "ORD-" + UUID.randomUUID().toString();

    // 주문 금액 계산
    Function<Order, Double> calculateTotal = order ->
        order.getAmount() * (1 + order.getTaxRate());
}

2. 회원 관리 시스템

public class UserSystem {
    // 유효한 이메일인지 확인
    Predicate<String> isValidEmail = email ->
        email.matches("^[A-Za-z0-9+_.-]+@(.+)$");

    // 회원 정보 출력
    Consumer<User> printUserInfo = user ->
        System.out.println(user.getName() + " (" + user.getEmail() + ")");

    // 새로운 유저 ID 생성
    Supplier<Long> userIdGenerator = () ->
        System.currentTimeMillis();

    // 유저 정보를 DTO로 변환
    Function<User, UserDTO> userToDTO = user ->
        new UserDTO(user.getId(), user.getName(), user.getEmail());
}

함수형 인터페이스 조합하기 ✨

여러 함수형 인터페이스를 체이닝해서 사용할 수 있습니다:

// Predicate 조합
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isEven = n -> n % 2 == 0;
Predicate<Integer> isPositiveAndEven = isPositive.and(isEven);

// Function 조합
Function<String, Integer> stringToInt = str -> Integer.parseInt(str);
Function<Integer, String> intToString = num -> String.valueOf(num);
Function<String, String> composed = stringToInt.andThen(intToString);

주의할 점 ⚠️

  1. 람다 표현식 내에서는 외부 변수가 final이어야 함
  2. 너무 복잡한 로직은 람다로 표현하지 않는 것이 좋음
  3. 예외 처리가 필요한 경우 별도의 메서드로 분리하는 것이 좋음

마치며 🎁

함수형 인터페이스를 활용하면:

  • 코드가 더 간결해지고
  • 재사용성이 높아지며
  • 테스트하기도 쉬워집니다!

처음에는 어려워 보일 수 있지만, 실제로 사용해보면 정말 편리하답니다! 😊


더 궁금하신 점이 있다면 댓글로 남겨주세요!

#Java #FunctionalInterface #Lambda #StreamAPI #ModernJava

728x90