[기술 정리] 스트림 API(Stream API)

lhs's avatar
Nov 20, 2024
[기술 정리] 스트림 API(Stream API)
💡
컬렉션 등의 데이터를 함수형 스타일로 처리할 수 있도록 제공된 데이터 처리 추상화 도구
 

1. 스트림 API란?

Java 8에서 도입된 기능으로, 컬렉션이나 배열 등의 데이터를 함수형 스타일로 처리할 수 있게 해주는 데이터 처리 도구다. 이를 통해 데이터를 필터링, 매핑, 정렬, 집계 등의 연산을 간결하고 효율적으로 수행할 수 있다. 스트림은 데이터를 변경하지 않고, 재사용할 수 없으며, 중간 연산과 최종 연산으로 나뉜다.

2. 예제

1. filter, toList, count

public class CountApp { public static void main(String[] args) { 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
    • filter는 스트림의 요소 중 조건을 만족하는 것만 추출하는 중간 연산자
    • 주어진 조건식에 맞는 요소들만 필터링하여 새로운 스트림을 반환한다.
    • filter(name -> name.length() > 3)은 이름 길이가 3보다 긴 문자열만 추출한다.
  • toList
    • toList는 스트림의 요소들을 리스트로 변환하는 최종 연산자
    • 스트림을 List로 수집하여 반환한다.
  • count
    • count는 스트림의 요소 개수를 셈으로써 결과를 반환하는 최종 연산자
    • 조건을 만족하는 요소의 개수를 반환한다.

2. map

public class MapApp { public static void main(String[] args) { 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
    • map은 각 요소를 변환하는 중간 연산자
    • 주어진 함수에 따라 스트림의 각 요소를 변환하여 새로운 스트림을 생성한다.
    • map(name -> name.toLowerCase())로 각 이름을 소문자로 변환한다.

3. sum, reduce

public class ReduceApp { public static void main(String[] args) { List<Integer> nums = Arrays.asList(1, 2, 3, 4); int sum = nums.stream().mapToInt(x -> x).sum(); System.out.println(sum); 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); } }
  • mapToInt
    • mapToInt는 스트림의 요소들을 int 값으로 변환하는 중간 연산자
    • mapToInt(x -> x)는 리스트의 요소들을 그대로 int형으로 변환한다.
    • sum 메서드를 사용하려면 IntStream으로 변환해야 한다.
  • sum
    • summapToInt로 변환된 int 스트림의 모든 값을 더하여 결과를 반환하는 최종 연산자
  • reduce
    • reduce는 스트림의 요소들을 순차적으로 결합하여 하나의 값을 생성하는 최종 연산자
    • reduce(5, (prev, next) -> prev + next)에서는 두 요소를 합산하는 방식으로 reduce를 사용하며 초기값 5부터 시작하여 각 요소와 결합한다.

4. sort, distinct

public class SortApp { public static void main(String[] args) { List<Integer> nums = Arrays.asList(5, 3, 1, 4, 2); nums.stream().sorted().distinct().forEach(System.out::println); } }
  • sort
    • sort는 스트림의 요소들을 정렬하는 중간 연산자
    • 기본적으로 오름차순으로 정렬되며, 내림차순 정렬을 원하면 Comparator.reverseOrder()를 사용할 수 있다.
  • distinct
    • distinct는 스트림의 중복 요소를 제거하는 중간 연산자
    • 요소들 중 중복되는 값을 제거하고 고유한 값만을 포함하는 스트림을 반환한다.
  • forEach
    • forEach는 스트림의 각 요소에 대해 주어진 동작을 수행하는 최종 연산자
    • 각 요소에 대해 System.out::println을 실행하여 출력한다.

5. group

public class GroupApp { public static void main(String[] args) { List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Bavid", "anna"); // Map<Character, List<String>> var groupData = names.stream().map(String::toUpperCase).collect(Collectors.groupingBy(s -> s.charAt(0))); System.out.println(groupData); } }
  • collect
    • collect는 스트림의 결과를 컬렉션으로 변환하는 최종 연산자
    • Collectors.groupingBy를 사용하여 스트림의 요소들을 그룹화하여 Map 형태로 반환한다.
  • groupingBy
    • groupingBy는 스트림의 요소를 특정 기준에 따라 그룹화하는 중간 연산자
    • 문자열의 첫 번째 문자를 기준으로 이름들을 그룹화하여 Map<Character, List<String>> 형태로 반환한다.
Share article

LHS's Study Space