공공부하자개발 · 영어 학습 노트
자바
고급모던 자바와 성능0/10 완료
  • 01제네릭과 와일드카드
  • 02멀티스레드와 동기화
  • 03람다식과 함수형 인터페이스
  • 04Stream API와 병렬 처리
  • 05Optional로 NPE 방지
  • 06메서드 활용 패턴 (고급)
  • 07Java 21 모던 문법
  • 08어노테이션·리플렉션·동적 프록시
  • 09CompletableFuture 심화와 가상 스레드 실전
  • 10JVM 메모리·GC·OOM 진단
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › 고급 › 03 / 10

람다식과 함수형 인터페이스

섹션 7진행 0 / 10
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

6. 연습 문제

문제 1

Retry 유틸을 작성하세요. static <T> T retry(int maxAttempts, Supplier<T> action) 은 action 이 예외를 던지면 최대 maxAttempts 번까지 재시도하고, 끝내 실패하면 마지막 예외를 RuntimeException 으로 감싸 던집니다. 3번째 호출에서만 성공하는 Supplier 로 테스트하고 시도 횟수를 출력하세요.

정답 보기
java
import java.util.function.Supplier;

public class Ex1 {
    static <T> T retry(int maxAttempts, Supplier<T> action) {
        RuntimeException last = null;
        for (int i = 1; i <= maxAttempts; i++) {
            try { return action.get(); }
            catch (RuntimeException e) { last = e; System.out.println("attempt " + i + " failed: " + e.getMessage()); }
        }
        throw new RuntimeException("all " + maxAttempts + " attempts failed", last);
    }

    public static void main(String[] args) {
        int[] calls = {0};
        String result = retry(5, () -> {
            if (++calls[0] < 3) throw new IllegalStateException("timeout");
            return "OK after " + calls[0];
        });
        System.out.println(result);
    }
}
// 출력:
// attempt 1 failed: timeout
// attempt 2 failed: timeout
// OK after 3

문제 2

record Employee(String name, String dept, int salary, int age) 목록을 (1) 부서 오름차순 (2) 급여 내림차순 (3) 나이 오름차순으로 정렬하는 Comparator 를 comparing 체인으로 만들고 정렬 결과의 이름만 출력하세요.

데이터: ("a","dev",500,30), ("b","dev",700,40), ("c","ops",500,25), ("d","dev",700,35).

정답 보기
java
import java.util.*;
import static java.util.Comparator.*;

public class Ex2 {
    record Employee(String name, String dept, int salary, int age) {}

    public static void main(String[] args) {
        List<Employee> list = new ArrayList<>(List.of(
            new Employee("a", "dev", 500, 30), new Employee("b", "dev", 700, 40),
            new Employee("c", "ops", 500, 25), new Employee("d", "dev", 700, 35)));
        list.sort(comparing(Employee::dept)
                .thenComparing(Employee::salary, reverseOrder())
                .thenComparingInt(Employee::age));
        System.out.println(list.stream().map(Employee::name).toList());
    }
}
// 출력:
// [d, b, a, c]

문제 3

문자열 처리 단계들을 Map<String, UnaryOperator<String>> 에 이름으로 등록하고(trim, upper, dedupe-spaces), 설정 문자열 "trim,dedupe-spaces,upper" 를 파싱해 그 순서대로 합성한 Function<String, String> 을 만들어 " hello lambda " 에 적용하세요.

없는 단계 이름이면 IllegalArgumentException 을 던지세요.

정답 보기
java
import java.util.*;
import java.util.function.*;

public class Ex3 {
    static final Map<String, UnaryOperator<String>> STEPS = Map.of(
        "trim", String::strip,
        "upper", String::toUpperCase,
        "dedupe-spaces", s -> s.replaceAll(" +", " ")
    );

    static Function<String, String> build(String config) {
        Function<String, String> f = Function.identity();
        for (String name : config.split(",")) {
            UnaryOperator<String> step = STEPS.get(name.strip());
            if (step == null) throw new IllegalArgumentException("unknown step: " + name);
            f = f.andThen(step);
        }
        return f;
    }

    public static void main(String[] args) {
        System.out.println("[" + build("trim,dedupe-spaces,upper").apply("  hello    lambda  ") + "]");
        try { build("trim,shout"); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); }
    }
}
// 출력:
// [HELLO LAMBDA]
// unknown step: shout
연습 문제
  • 문제 1
  • 문제 2
  • 문제 3
이전 섹션5 자주 하는 실수 (Tip)6 / 7다음 섹션7 정리