Stream 스트림
- 다양한 데이터 소스를 표준화된 방법으로 다루기 위한 것
- 데이터의 연속적인 흐름
- 컬렉션 프레임워크
- List, Set 과 Map 이 사용 방법이 달라 표준화 실패
- JDK 1.8 스트림부터 진정한 통일된 표준화
- 데이터 소스
- 컬렉션 (List, Set, Map)
- 배열
- 람다식
스트림으로 변환
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> intStream = list.stream();
Stream<String> strStream = Stream.of(new String[] {"a", "b", "c"});
Stream<Integer> evenStream = Stream.iterate(0, n->n+2);
Stream<Double> randomStream = Stream.generate(Math::random);
IntStream intStream = new Random().ints(5);
스트림 작업 순서
stream.distinct().limit(5).sorted().forEach(System.out::println)
- 스트림 만들기
- 중간 연산 (0번 ~ n번)
- 연산 결과가 스트림인 연산
- 반복적으로 적용 가능
- 최종 연산 (결과 - 1번)
- 연산 결과가 스트림이 아닌 연산
- 단 한번만 적용 가능 (스트림의 요소를 소모)
- 최종 연산 후에 stream 이 닫힌다.
스트림의 특징
- 데이터 소스로부터 데이터를 읽기만할 뿐 변경하지 않는다. (⚠️ Read Only)
- Iterator 처럼 일회용이다. (필요하면 다시 스트림 생성)
- 최종 연산 전까지 중간 연산이 수행되지 않는다. - 지연된 연산
- 스트림 작업을 내부 반복으로 처리한다. (코드가 간결해진다.) -
forEach()
- 스트림 작업을 병렬로 처리 - 병렬 스트림
parallel()
- 기본형 스트림 -
IntStream
, LongStream
, DoubleStream
- 오토 박싱 & 언박싱의 비효율이 제거된다. (성능 개선)
Stream<Integer>
대신 IntStream
사용
- 숫자와 관련된 유용한 메서드를
Stream<T>
보다 더 많이 제공
스트림 만들기 - 컬렉션
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> intStream = list.stream();
intStream.forEach(System.out::print);
intStream.forEach(System.out::print);
stream()
Collection
인터페이스의 stream()
으로 컬렉션을 스트림으로 변환
스트림 만들기 - 배열
Stream<String> strStream = Stream.Of("a", "b", "c");
Stream<String> strStream = Stream.Of(new String[]{"a", "b", "c"});
Stream<String> strStream = Arrays.stream(new String[]{"a", "b", "c"});
Stream<String> strStream = Arrays.stream(new String[]{"a", "b", "c"}, 0, 3);
Stream.Of()
Arrays.stream()
- 객체 배열로부터 스트림 생성하기
IntStream intStream = IntStream.Of(1, 2, 3);
IntStream intStream = IntStream.Of(new int[]{1, 2, 3});
IntStream intStream = Arrays.stream(new int[]{1, 2, 3});
IntStream intStream = Arrays.stream(new int[]{1, 2, 3}, 0, 3);
IntStream.Of()
- 기본형 배열로부터 스트림 생성하기
- 숫자와 관련된 편리한 메서드 추가 제공 및 성능 향상
스트림 만들기 - 임의의 수
IntStream intStream = new Random().ints();
intStream.limit(5).forEach(System.out::println);
IntStream intStream = new Random().ints(5);
Integer.MIN_VALUE <= ints() <= Integer.MAX_VALUE
Long.MIN_VALUE <= longs() <= Long.MAX_VALUE
0.0 <= doubles() < 1.0
- 난수를 요소로 갖는 스트림 생성하기
- 지정된 범위의 난수를 요소로 갖는 스트림을 생성하는 메서드 (Random 클래스)
스트림 만들기 - 특정 범위의 정수
IntStream intStream = IntStream.range(1, 5);
IntStream intStream = IntStream.rangeClosed(1, 5);
- 특정 범위의 정수를 요소로 갖는 스트림 생성하기
rangeClosed()
는 범위 끝 포함
스트림 만들기 - 람다식 iterate()
, generate()
Stream<Integer> evenStream = Stream.iterate(0, n->n+2);
iterate()
는 이전 요소를 seed
(초기값) 로 해서 다음 요소를 계산
Stream<Double> randomStream = Stream.generate(Math::random);
Stream<Integer> oneStream = Stream.generate(()->1);
generate()
는 seed
(초기값) 를 사용하지 않는다.
스트림 만들기 - 파일과 빈 스트림
Stream<String> Files.lines(Path path)
- 파일 소스로 하는 스트림 생성하기
- log 파일 생성시 사용
Stream emptyStream = Stream.empty();
long count = emptyStream.count();