스트림(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();
}
}
}
⊙ 참고 문헌
- 이병승, 「초보 개발자를 위한 자바:한 권으로 배우는 자바 마스터 가이드 북」, 영진닷컴, 2024, p1249 - 1255
- 마종현, 「백엔드 취업 파트타임 스쿨 5기:Part 01. Java 기초-Chapter 01. Java 프로그래밍-02.변수와 자료형」, 제로베이스, 2024, https://zero-base.co.kr/