[자바/심화] 스트림 :: 스트림 생성

스트림(Stream)이란?

- 배열, 컬렉션 등의 데이터를 하나씩 참조하여 코드를 실행할 수 있는 기능을 제공한다.

- 람다식을 사용해서 간결하게 요소들을 다룰 수 있다.

- 대량의 데이터를 병렬로 처리할 수 있다. 이를 통해 대량의 데이터에서 평균값, 최대값, 조건에 맞는 결과값, 통계 등을 쉽게 얻을 수 있다.

- 데이터를 최종 처리하기 전에 여러 가지 중간 처리를 할 수 있다.

- 스트림은 크게 3가지로 구성되며, 스트림 생성(원본 스트림) ▶ 중개 연산(필터링 스트림, 매핑 스트림)  ▶ 최종 연산(최종 처리 스트림) 과정으로 구성되어 있다.

스트림 종류

- 자바에서 제공하는 스트림 클래스를 이용하면 여러 가지 데이터 소스에서 데이터 스트림으로 변환해서 일관성 있고 빠르게 처리할 수 있다.

- 자주 사용되는 데이터 소스들에 대한 스트림 클래스들이며, API 문서를 참고하여 사용하고자 하는 데이터 타입의 스트림 클래스를 확인할 수 있다.

리턴 타입 메서드 데이터 소스
  Stream<T>   java.util.Collection.stream()
  java.util.Collection.paralleStream()
  컬렉션
  Stream<T>   Arrays.stream(T[ ])
  Arrays.stream(Int[ ])
  배열
  IntStream   IntStream.range(int, int)
  IntStream.rangeClosed(int, int)
  int 범위
  LongStream   LongStream.range(long, long)
  LongStream.rangeClosed(long, long)
  long 범위
  Stream<Path>   Files.find(Path, int, BiPredicate, FileVisitOption)   디렉터리
  Stream<String>   Files.lines(Path, Charset)   텍스트 파일
  IntStream   Randoms.ints()   랜덤 수

스트림 생성

컬렉션에서 스트림 얻기

- List에서 stream() 메소드를 호출해서 스트림 객체를 얻는다.

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

public class Main {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("홍길동", "고길동", "이지함", "안중근");

        // 리스트에서 스트림 생성
        Stream<String> stream = list.stream();
        stream.forEach(System.out::println);
        /*
            홍길동
            고길동
            이지함
            안중근
        */
    }
}

배열에서 스트림 얻기

- 배열에서도 컬렉션에서 스트림 객체를 얻는 것과 동일한 방법으로 스트림 객체를 얻는다.

- 배열의 타입이 기본 타입인 경우 각각의 기본 타입을 빠르게 처리할 수 있는 스트림 클래스를 제공한다.

- int 타입의 배열은 intStream으로 처리하면 빠르게 처리할 수 있다.

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

public class Main {
    public static void main(String[] args) {
        String[] array = {"홍길동", "고길동", "이지함", "안중근"};

        // 배열에서 스트림 생성
        Stream<String> stream = Arrays.stream(array);
        stream.forEach(System.out::println);
        /*
            홍길동
            고길동
            이지함
            안중근
        */
        
        int[] intArr = {2, 4, 6, 8};
        // 정수 타입 배열은 IntStream으로 빠르게 처리할 수 있다.
      	IntStream intStream = Arrays.stream(intArr);
        intStream.forEach(System.out::println);
        /*
            2
            4
            6
            8
        */
    }
}

특정 정수 범위에서 스트림 얻기

- IntStream의 range()나 rangeClosed() 메소드를 사용하면 숫자 데이터에서 두 수 사이의 숫자를 얻을 수 있다.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
      	IntStream intStream1 = IntStream.range(0, 100);        // 마지막 숫자를 포함하지 않는다.
      	IntStream intStream2 = IntStream.rangeClosed(0, 100);  // 마지막 숫자까지 포함한다.
        
        // sum() 메서드를 사용한 합계 계산
        System.out.println("IntStream.range(0, 100) => Sum = " + intStream1.sum());
        System.out.println("IntStream.rangeClosed(0, 100) => Sum = " + intStream2.sum());
    }
}

랜덤 수에서 스트림 얻기

- Random 클래스의 ints(), longs(), doubles() 메서드를 이용해서 스트림을 얻을 수 있다.

- 메서드의 매개변수로 랜덤 수의 개수를 지정해구고, 매개 변수가 두 개인 ints() 메서드는 랜덤 수의 범위를 지정할 수 있다.

import java.util.Random;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        IntStream intStream1 = new Random().ints(3);  // 3개의 랜덤한 정수를 얻는다.
        intStream1.forEach(System.out::println);
        /*
            1214990110
            937487609
            -216990598
        */

      	IntStream intStream2 = new Random().ints(1, 30).limit(5);  // 1에서 30 사이의 정수를 얻은 후, 5개 출력한다.
        intStream2.forEach(System.out::println);
        /*
            16
            20
            21
            2
            19
        */
    }
}

파일로부터 스트림 얻기

- Files 클래스의 정적 메서드인 lines()로 파일에서 스트림을 얻을 수 있다.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        Path path = Paths.get("sample.txt");

        try (Stream<String> stream = Files.lines(path)) {
            stream.forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

⊙ 참고 문헌

  1. 이병승, 「초보 개발자를 위한 자바:한 권으로 배우는 자바 마스터 가이드 북」, 영진닷컴, 2024, p1249 - 1255
  2. 마종현, 「백엔드 취업 파트타임 스쿨 5기:Part 01. Java 기초-Chapter 01. Java 프로그래밍-02.변수와 자료형」, 제로베이스, 2024, https://zero-base.co.kr/