본문 바로가기

기술 학습

JAVA 스트림(Stream) API 개념과 활용

1. 스트림(Stream)이란?

스트림(Stream)은 Java 8에서 도입된 기능으로, 컬렉션(Collection) 데이터를 처리하는 기능을 제공합니다. 반복문을 사용하지 않고도 간결하고 효율적으로 데이터를 처리할 수 있도록 도와줍니다.

스트림의 주요 특징:

  • 연속적인 데이터 처리: 컬렉션, 배열 등의 데이터를 하나씩 처리할 수 있음
  • 중간 연산과 최종 연산 지원: 필터링, 매핑, 정렬 등의 중간 연산 후 최종 연산 실행
  • 내부 반복 방식: 기존의 for문과 다르게 내부적으로 처리하여 코드 가독성을 높임
  • 병렬 처리 지원: 멀티코어 환경에서 성능을 향상시킬 수 있음

2. 스트림 생성 방법

스트림은 다양한 방법으로 생성할 수 있으며, 가장 일반적으로 Collection에서 스트림을 생성하는 방법이 사용됩니다.

2.1 리스트(List)에서 스트림 생성

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("Apple", "Banana", "Cherry");
        Stream<String> stream = list.stream();
        
        stream.forEach(System.out::println);
    }
}

2.2 배열에서 스트림 생성

import java.util.stream.Stream;

public class StreamFromArray {
    public static void main(String[] args) {
        String[] fruits = {"Apple", "Banana", "Cherry"};
        Stream<String> stream = Stream.of(fruits);
        
        stream.forEach(System.out::println);
    }
}

2.3 숫자 범위에서 스트림 생성

import java.util.stream.IntStream;

public class IntStreamExample {
    public static void main(String[] args) {
        IntStream.range(1, 5).forEach(System.out::println);
    }
}

3. 스트림의 중간 연산 (Intermediate Operations)

중간 연산은 데이터를 변환하거나 필터링하는 과정이며, 최종 연산이 호출될 때까지 실행되지 않습니다.

3.1 필터(filter)

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FilterExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("John", "Jane", "Jack", "Jill");
        List<String> filteredNames = names.stream()
                                          .filter(name -> name.startsWith("J"))
                                          .collect(Collectors.toList());
        
        System.out.println(filteredNames);
    }
}

3.2 매핑(map)

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class MapExample {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("hello", "world");
        List<String> upperCaseWords = words.stream()
                                           .map(String::toUpperCase)
                                           .collect(Collectors.toList());
        
        System.out.println(upperCaseWords);
    }
}

3.3 정렬(sorted)

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class SortedExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(5, 3, 8, 1, 2);
        List<Integer> sortedNumbers = numbers.stream()
                                             .sorted()
                                             .collect(Collectors.toList());
        
        System.out.println(sortedNumbers);
    }
}

4. 스트림의 최종 연산 (Terminal Operations)

최종 연산은 스트림의 데이터를 처리하고 결과를 반환하는 연산입니다.

4.1 forEach

import java.util.Arrays;
import java.util.List;

public class ForEachExample {
    public static void main(String[] args) {
        List<String> fruits = Arrays.asList("Apple", "Banana", "Cherry");
        fruits.stream().forEach(System.out::println);
    }
}

4.2 collect (리스트로 변환)

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class CollectExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
        List<String> upperCaseNames = names.stream()
                                           .map(String::toUpperCase)
                                           .collect(Collectors.toList());
        
        System.out.println(upperCaseNames);
    }
}

4.3 count (요소 개수 구하기)

import java.util.Arrays;
import java.util.List;

public class CountExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
        long count = names.stream().count();
        
        System.out.println("요소 개수: " + count);
    }
}

5. 병렬 스트림 (Parallel Stream)

스트림은 기본적으로 순차적으로 실행되지만, 병렬 스트림을 사용하면 여러 개의 작업을 동시에 처리할 수 있습니다.

import java.util.Arrays;
import java.util.List;

public class ParallelStreamExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
        names.parallelStream().forEach(System.out::println);
    }
}

6. 결론

이번 글에서는 Java 스트림(Stream) API의 개념과 활용법을 다뤘습니다. 스트림을 사용하면 코드의 가독성을 높이고, 성능을 향상시킬 수 있습니다.

다음 글에서는 **람다 표현식(Lambda Expressions)**을 활용한 함수형 프로그래밍에 대해 알아보겠습니다!