본문 바로가기

자바

[JAVA] Stream

728x90

1. 목적

스트림(Stream)은 데이터를 연속적으로 처리하는 기능을 제공하는 Java의 API이다.

즉, 컬렉션(List, Set), 배열, 파일 등의 데이터를 간결하고 효율적으로 다룰 수 있도록 해준다.

스트림을 사용하는 이유

  1. 반복문을 줄여 가독성을 높임
    • for 문 없이 map(), filter() 등을 활용해 간결한 코드 작성 가능
  2. 병렬 처리(Parallel Processing) 지원
    • 대량의 데이터를 더 빠르게 처리 가능 (parallelStream())
  3. 불변(Immutable)한 데이터 처리
    • 기존 데이터를 변경하지 않고 새로운 스트림을 생성하여 처리

2. 특징

  • 데이터를 한 방향으로 흘려보내는 방식으로 요소를 한 번씩 처리하며, 다시 사용할 수 없다.
  • 불변(Immutable) 기존 데이터를 변경하지 않고 새 값을 생성한다.
  • 중간 연산과 최종 연산 구분 map(), filter() 등 중간 연산 후 collect(), forEach() 같은 최종 연산이 필요로 한다.
  • 병렬 처리 가능 parallelStream()을 사용하면 멀티코어를 활용한 병렬 처리 가능하다.
  • 지연 연산(Lazy Evaluation) 최종 연산이 호출될 때까지 연산이 수행되지 않는다.

3. 사용 예시

1. 스트림 생성

  • 배열에서 스트림 생성
   import java.util.Arrays;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        String[] words = {"Java", "Python", "C++"};

        // 배열을 스트림으로 변환
        Stream<String> stream = Arrays.stream(words);

        // 스트림 출력
        stream.forEach(System.out::println);
    }
}
  • 컬렉션에서 스트림 생성
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> list = List.of("Apple", "Banana", "Orange");

        // List에서 스트림 생성
        list.stream().forEach(System.out::println);
    }
}
  • 숫자 스트림 생성 (IntStream, DoubleStream)
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        // 1부터 5까지 숫자 스트림 생성
        IntStream.rangeClosed(1, 5).forEach(System.out::print);
        // 출력: 12345
    }
}

2. 스트림의 중간 연산

중간 연산(Intermediate Operation)은 데이터를 가공하는 역할을 한다.

  • filter(): 특정 조건의 요소만 추출
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5, 6};

        // 짝수만 출력
        Arrays.stream(numbers)
              .filter(n -> n % 2 == 0)
              .forEach(System.out::print);
        // 출력: 246
    }
}
  • map(): 요소를 변환
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3};

        // 모든 숫자를 2배로 변환
        Arrays.stream(numbers)
              .map(n -> n * 2)
              .forEach(System.out::print);
        // 출력: 246
    }
}
  • sorted(): 정렬
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        String[] words = {"Banana", "Apple", "Orange"};

        Arrays.stream(words)
              .sorted()
              .forEach(System.out::println);
    }
}

3. 스트림의 최종 연산

최종 연산(Terminal Operation)은 스트림을 소비(consume)하고 결과를 반환한다.

  • forEach(): 각 요소 출력
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> fruits = List.of("Apple", "Banana", "Orange");

        fruits.stream().forEach(System.out::println);
    }
}
  • count(): 요소 개수 세기
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        long count = Arrays.stream(new int[]{1, 2, 3, 4, 5})
                           .count();
        System.out.println(count); // 5
    }
}
  • reduce(): 누적 연산 수행
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int sum = Arrays.stream(new int[]{1, 2, 3, 4, 5})
                        .reduce(0, Integer::sum);

        System.out.println(sum); // 15
    }
}
  • collect(): 스트림을 리스트로 변환
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<String> list = List.of("Java", "Python", "C++");

        // 리스트로 변환
        List<String> filteredList = list.stream()
                                        .filter(s -> s.length() > 3)
                                        .collect(Collectors.toList());

        System.out.println(filteredList); // [Java, Python]
    }
}

4. 병렬 스트림

java 스트림은 병렬 처리를 지원하여 속도를 높일 수 있다.

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> words = List.of("Apple", "Banana", "Orange");

        // 병렬 스트림 처리
        words.parallelStream()
             .forEach(System.out::println);
    }
}
  • `parallelStream()을 사용하면 내부적으로 멀티코어 CPU를 활용하여 데이터 처리 속도를 높일 수 있음
728x90

'자바' 카테고리의 다른 글

[JAVA] 추상 클래스(abstract)  (0) 2025.03.13
[JAVA] 상속  (0) 2025.03.12
[JAVA] 배열(Array)  (0) 2025.03.11
[JAVA] record  (0) 2025.03.11
[JAVA] 오버로딩, 오버라이딩  (0) 2025.03.06