본문 바로가기
프로그래밍/JAVA

Java Streams API - 2

by 낭만프로그래머. 2024. 5. 26.

Java Streams API의 중간 연산은 스트림을 변환하거나 필터링하는 작업을 수행하며, 항상 또 다른 스트림을 반환합니다. 중간 연산은 지연 평가(lazy evaluation) 방식으로 동작하여, 최종 연산이 호출되기 전까지는 실제로 수행되지 않습니다. 이는 스트림 파이프라인의 효율성을 높이고, 필요 이상의 연산을 피하는 데 도움을 줍니다.

다음은 주요 중간 연산과 그 동작 방식에 대한 자세한 설명입니다.

주요 중간 연산

  1. filter
    • 주어진 조건(predicate)에 맞는 요소들만 포함하는 스트림을 반환합니다.
    • 사용 예:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream()
                                   .filter(n -> n % 2 == 0)
                                   .collect(Collectors.toList());
// 결과: [2, 4]
  1. map
    • 각 요소를 주어진 함수에 따라 변환하여 새로운 요소로 구성된 스트림을 반환합니다.
    • 사용 예:
List<String> words = Arrays.asList("hello", "world");
List<Integer> wordLengths = words.stream()
                                 .map(String::length)
                                 .collect(Collectors.toList());
// 결과: [5, 5]
  1. flatMap
    • 각 요소를 스트림으로 변환하고, 이 스트림들을 하나의 평면화된 스트림으로 병합합니다.
    • 사용 예:
List<List<String>> listOfLists = Arrays.asList(
    Arrays.asList("a", "b"),
    Arrays.asList("c", "d"));
List<String> flatList = listOfLists.stream()
                                   .flatMap(List::stream)
                                   .collect(Collectors.toList());
// 결과: [a, b, c, d]
  1. distinct
    • 중복된 요소를 제거한 스트림을 반환합니다.
    • 사용 예:
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3);
List<Integer> distinctNumbers = numbers.stream()
                                       .distinct()
                                       .collect(Collectors.toList());
// 결과: [1, 2, 3]
  1. sorted
    • 스트림의 요소를 정렬된 순서로 반환합니다. 기본 정렬 순서나 사용자 정의 비교자(comparator)를 사용할 수 있습니다.
    • 사용 예:
List<String> words = Arrays.asList("banana", "apple", "cherry");
List<String> sortedWords = words.stream()
                                .sorted()
                                .collect(Collectors.toList());
// 결과: [apple, banana, cherry]
  1. peek
    • 각 요소를 소비하지 않고, 중간에 요소를 보고 싶을 때 사용합니다. 주로 디버깅 목적으로 사용됩니다.
    • 사용 예:
       
List<String> words = Arrays.asList("one", "two", "three");
words.stream()
     .peek(System.out::println)
     .map(String::toUpperCase)
     .collect(Collectors.toList());
// 결과: 출력 - one, two, three
  1. limit
    • 스트림의 요소 개수를 제한합니다.
    • 사용 예:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> limitedNumbers = numbers.stream()
                                      .limit(3)
                                      .collect(Collectors.toList());
// 결과: [1, 2, 3]
  1. skip
    • 처음 n개의 요소를 건너뛰고 나머지 요소들로 구성된 스트림을 반환합니다.
    • 사용 예:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> skippedNumbers = numbers.stream()
                                      .skip(2)
                                      .collect(Collectors.toList());
// 결과: [3, 4, 5]

지연 평가(lazy evaluation)

중간 연산은 최종 연산이 호출될 때까지 실제로 수행되지 않습니다. 이는 스트림 파이프라인의 성능을 최적화하는 데 도움을 줍니다. 예를 들어, 스트림의 모든 요소에 대해 filter와 map 연산이 정의되어 있더라도, 최종 연산이 호출될 때 필요한 만큼의 요소에 대해서만 연산이 수행됩니다.

중간 연산의 연결

여러 중간 연산을 연결하여 복잡한 데이터 처리 파이프라인을 만들 수 있습니다. 이러한 파이프라인은 각 중간 연산이 다음 연산으로 스트림을 전달하면서 자연스럽게 연결됩니다.

예제:

List<String> words = Arrays.asList("apple", "banana", "cherry", "date");

List<String> result = words.stream()
                           .filter(word -> word.startsWith("a"))
                           .map(String::toUpperCase)
                           .sorted()
                           .collect(Collectors.toList());
// 결과: [APPLE]

위의 예제에서, 스트림은 filter, map, sorted 연산을 거쳐 최종적으로 결과 리스트를 생성합니다.

이처럼 Java Streams API의 중간 연산은 데이터 처리 파이프라인을 구성하는 중요한 요소로, 다양한 데이터를 효율적으로 변환하고 필터링하는 데 사용됩니다.

'프로그래밍 > JAVA' 카테고리의 다른 글

Java stream 의 Optional.orElseThrow  (0) 2024.07.28
Multi Datasource 를 이용한 database routing 전략  (0) 2024.07.06
Java Streams API - 3  (0) 2024.05.26
Java Streams API - 1  (0) 2024.05.26