(Java) Stream Api

화낼거양's avatar
Nov 20, 2024
(Java) Stream Api
 
 
💡
Java의 Stream API는 Java 8에서 도입된 기능으로, 컬렉션 데이터를 다루는 데 있어 더 효율적이고 선언적인 방법을 제공합니다. Stream API는 컬렉션에 저장된 데이터를 처리(필터링, 정렬, 변환 등)하는데 유용하며, 함수형 프로그래밍 스타일을 지원합니다.
기존의 입출력 스트림과는 전혀 다른 개념이니 혼동하지 않도록 합니다.
 

주요 개념

  1. Stream:
      • 데이터의 순차적인 흐름을 나타냅니다. 컬렉션에서 데이터를 추출하여 스트림을 생성할 수 있습니다.
  1. 중간 연산 (Intermediate Operations):
      • 스트림을 변환하지만, 결과를 최종적으로 반환하지 않는 연산입니다. 중간 연산은 항상 또 다른 스트림을 반환하며, 이는 체이닝(chaining)될 수 있습니다. 예: filter, map, sorted.
  1. 최종 연산 (Terminal Operations):
      • 스트림을 처리하고 결과를 반환합니다. 최종 연산이 호출되면 스트림의 데이터가 소비되며, 이후에 스트림을 다시 사용할 수 없습니다. 예: forEach, collect, reduce.
 
 
 
 

예제 1: Count

 
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David"); List<String> r1 = names.stream().filter(name -> name.length() > 3).toList(); r1.forEach(s -> System.out.println(s)); Long r2 = names.stream().filter(name -> name.length() > 3).count(); System.out.println(r2);
 
  • 설명:
    • filter: 이름의 길이가 3보다 큰 요소만 필터링합니다.
    • toList: 필터링된 결과를 리스트로 반환합니다.
    • forEach: 결과를 하나씩 출력합니다.
    • count: 필터링된 요소의 개수를 세고 출력합니다.
  • 결과:
    • 필터링된 리스트 출력: "Alice", "Charlie", "David"
    • 필터링된 요소의 개수 출력: 3
 
 

예제 2: Sort

 
List<Integer> nums = Arrays.asList(5, 3, 1, 4, 2, 5); // 정렬을 한 뒤, 중복을 제거하고, 반복문으로 출력한다. nums.stream().sorted().distinct().forEach(integer -> System.out.println(integer));
 
  • 설명:
    • sorted: 리스트의 요소를 오름차순으로 정렬합니다.
    • distinct: 중복된 요소를 제거합니다.
    • forEach: 정렬되고 중복이 제거된 요소를 하나씩 출력합니다.
  • 결과:
    • 출력: 1, 2, 3, 4, 5
 
 

예제 3: Map

 
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David"); List<String> newNames = names.stream().map(name -> name.toLowerCase()) .filter(name -> name.length() > 3) .toList(); newNames.forEach(name -> System.out.println(name));
 
  • 설명:
    • map: 각 이름을 소문자로 변환합니다.
    • filter: 이름의 길이가 3보다 큰 요소만 필터링합니다.
    • toList: 필터링된 결과를 리스트로 반환합니다.
    • forEach: 결과를 하나씩 출력합니다.
  • 결과:
    • 출력: "alice", "charlie", "david"
 
 

예제 4: Group

 
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "anna"); // 리턴 타입 : Map<Character, List<String>> // 최근 버전은 var로 모든 형을 대체해서 쓸 수 있게 패치되었다. var groupData = names.stream() .map(name -> name.toUpperCase()) .collect(Collectors.groupingBy(name -> name.charAt(0))); System.out.println(groupData);
 
  • 설명:
    • map: 각 이름을 대문자로 변환합니다.
    • collect: 이름의 첫 글자를 기준으로 그룹화하여 Map으로 반환합니다.
    • Collectors.groupingBy: 그룹화를 수행하는 수집기(collector)를 사용합니다.
  • 결과:
    • 출력: {A=[ALICE, ANNA], B=[BOB], C=[CHARLIE], D=[DAVID]}
 
 

예제 5: Reduce (조인)

 
List<Integer> nums = Arrays.asList(1, 2, 3, 4); int sum1 = nums.stream().mapToInt(x -> x).sum(); System.out.println(sum1); int sum2 = nums.stream().reduce(5, (prev, next) -> { System.out.println("prev : " + prev); System.out.println("next : " + next); System.out.println("----------"); return prev + next; }); System.out.println(sum2);
 
  • 설명:
    • mapToIntsum: 스트림의 모든 요소를 정수형으로 변환하고 합계를 계산합니다.
    • reduce: 초기값 5를 가지고, 스트림의 모든 요소를 더하여 최종 합계를 계산합니다. 중간 값(prevnext)을 출력합니다.
  • 결과:
    • sum1: 10 (1 + 2 + 3 + 4)
    • sum2: 15 (5 + 1 + 2 + 3 + 4)
Share article

moohyun