본문 바로가기
Spring

[8] 자바 고급 문법 - 람다 & 스트림

by 민지기il 2025. 3. 31.

[1] 람다 기본

1) 람다: 함수를 하나의 값처럼 표현하는 방식이다. 자바에서는 주로 짧은 형태의 익명 함수를 표현할 때 사용한다.

Runnable r = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello");
    }
};
//아래와 같이 바뀐다.
Runnable r = () -> System.out.println("Hello");

() → 매개변수, -> → 람다 화살표, {} → 실행 내용

2) 함수형 인터페이스: 메서드가 하나만 있는 인터페이스

@FunctionalInterface
interface MyPrinter {
    void print(String msg);
}

@FuntionalInterface를 사용해 함수형 인터페이스임을 검증함

3) 람다와 시그니처: 시그니처 - 매개변수와 리턴타입

@FunctionalInterface
interface Calculator {
    int calc(int a, int b);
}
//람다로 쓰면..
Calculator sum = (a, b) -> a + b;
System.out.println(sum.calc(10, 20));  // 30

4) 람다의 전달: 람다식은 값처럼 변수에 담을수도, 메서드 인자로도 전달이 가능하다.

@FunctionalInterface
interface Printer {
    void print(String message);
}

public class LambdaDemo {
    static void printMessage(Printer printer) {
        printer.print("메시지 전달!");
    }

    public static void main(String[] args) {
        printMessage(msg -> System.out.println("출력: " + msg));
    }
}

printMessage()함수에 람다식을 직접 전달함!

[2] 람다 활용

1) filter: 조건에 맞는 요소만 걸러내기

List<String> names = List.of("Alice", "Bob", "Charlie", "David");

List<String> result = names.stream()
    .filter(name -> name.length() <= 4)
    .collect(Collectors.toList());

System.out.println(result); // [Bob]

stream()으로 리스트를 스트림으로 만들고

filter() 안의 람다식에서 조건(name.length() <= 4)을 설정해서 조건을 만족하는 항목만 남김

마지막에 collect()로 리스트로 다시 모음

List<Integer> values = Arrays.asList(5, 1, 240, 4, 43, 81, 59, 33, 36);

List<Integer> result = values.stream()
    .filter(number -> number < 50)
    .distinct()
    .sorted(Integer::compare)
    .collect(Collectors.toList());

2) map: 요소들을 변환하기

List<String> names = List.of("Alice", "Bob");

List<Integer> nameLengths = names.stream()
    .map(name -> name.length())
    .collect(Collectors.toList());

System.out.println(nameLengths); // [5, 3]

3) filter & map 

List<String> names = List.of("Alice", "Bob", "Charlie", "Amy");

List<String> shortUpperNames = names.stream()
    .filter(name -> name.length() <= 4)    // 짧은 이름만
    .map(name -> name.toUpperCase())       // 대문자로 변환
    .collect(Collectors.toList());

System.out.println(shortUpperNames); // [BOB, AMY]

4) 람다 & stream 패턴

list.stream()
    .filter(조건)
    .map(변환)
    .collect(Collectors.toList());

[3] 람다와 스트림

1) reduce() - 누적해서 하나의 값 만들기

List<Integer> numbers = List.of(1, 2, 3, 4, 5);

int sum = numbers.stream()
    .reduce(0, (a, b) -> a + b);  // 초기값 0부터 시작해 계속 더함
System.out.println(sum); // 15

2) sorted() - 정렬하기

List<String> names = List.of("Charlie", "Alice", "Bob");

List<String> sortedNames = names.stream()
    .sorted()
    .collect(Collectors.toList());
System.out.println(sortedNames); // [Alice, Bob, Charlie]

오름차순이 정렬의 기본값임

내림차순: .sorted(Comparator.reverseOrder())

3) distinct() - 중복 제거

List<Integer> numbers = List.of(1, 2, 2, 3, 3, 3, 4);

List<Integer> distinctNumbers = numbers.stream()
    .distinct()
    .collect(Collectors.toList());
System.out.println(distinctNumbers); // [1, 2, 3, 4]

[4] 익명 클래스

: 이름 없는 클래스를 1회성으로 선언해서 바로 객체를 만들고 사용하는 것

Runnable task = new Runnable() {
    @Override
    public void run() {
        System.out.println("익명 클래스 실행");
    }
};
task.run();  // 실행 결과: 익명 클래스 실행
// 람다식으로 줄이면
Runnable task = () -> System.out.println("람다 실행");
task.run();  // 실행 결과: 람다 실행

[5] Optional

    public static void main(String[] args) {
        Optional <String> opt1 = Optional.empty();
        //of(value/null): null이 아닌 데이터 생성
        String str = "of";
        str = null;
        Optional<String> opt2 = Optional.of(str);
        //ofNullable(value / null): null일 수도 있는 값이 들어가는 경우
        Optional <String> opt2 = Optional.ofNullable(str);
        System.out.println(opt2);
    }

'Spring' 카테고리의 다른 글

[7] 자바 고급 문법 - 문자  (0) 2025.03.28
[6] 자바 중급 문법 - List  (0) 2025.03.28
[5] 자바 중급 문법 - ArrayList  (0) 2025.03.28
[4] 자바 중급 문법 - Generic  (0) 2025.03.26
[3] 자바 중급 문법 3 -- 날짜와 시간  (0) 2025.03.21