스트림(Stream)
- 다양한 데이터 소스를 표준화된 방법으로 다루기 위한 것
- 스트림이 제공하는 기능 - 중간 연산과 최종 연산
- 중간 연산 - 연산결과가 스트림이 연산. 반복적으로 적용가능
- 최종 연산 - 연산결과가 스트림이 아닌 연산. 단 한번만 적용가능 (스트림 요소를 소모)
스트림의 특징
- 스트림은 데이터 소스로부터 데이터를 읽기만할 뿐 변경하지 않는다.
- 스트림은 Iterator처럼 일회용이다. (필요하면 다시 스트림을 생성해야 함)
- 최종 연산 전까지 중간연산이 수행되지 않는다. - 지연된 연산
- 스트림은 작업을 내부 반복으로 처리한다.
- 스트림의 작업을 병렬로 처리 - 병렬스트림
- 기본형 스트림 - IntStream, LongStream, DoubleStream
- 오토박싱 & 언박싱의 비효율이 제거됨 (Stream<Integer> 대신 IntStream을 사용)
- 숫자와 관련된 유용한 메서드를 Stream<T>보다 더 많이 제공
스트림 만들기 - 컬렉션
- Collection 인터페이스의 stream()으로 컬렉션을 스트림으로 변환
- stream은 1회용임.
Stream<E> stream() // Collection 인터페이스의 메서드
List<Integer> list = Arrays.asList(1,2,3,4,5);
Stream<Integer> intStream = list.stream(); //list 기준으로 하는 stream이 생성
// 스트림의 모든 요소를 출력
intStream.forEach(System.out::print) // 12345
스트림 만들기 - 배열
- 기본형 스트림은 sum(), average(), count() 함수 등을 지원
Stream<String> strStream = Stream.of(new String[] {"a","b","c","d"});
strStream.forEach(System.out::println);
int[] intArr = {1,2,3,4,5};
IntStream intStream = Arrays.stream(intArr);
intStream.forEach(System.out::println);
스트림 만들기 - 난수
// IntStream intStream = new Random().ints(); // 무한 스트림
IntStream intStream = new Random().ints(10,5,10); // 5~9까지의 난수를 10번만 출력
intStream
// .limist(10); 10개씩 자르기
.forEach(System.out::println);
스트림 만들기 - 특정범위의 정수
- IntStream, LongStream
- .close()를 이용하면 마지막 수도 포함하는 범위를 가짐
IntStream intStream = IntStream.range(1,5); // 1,2,3,4
IntStream intStream = IntStream.range.Closed(1,5); // 1,2,3,4,5
스트림 만들기 - 람다식
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f) // 이전 요소에 종속적
static <T> Stream<T> generate(Supplier<T> s) // 이전 요소에 독립적
- iterate()는 이전 요소를 seed로 해서 다음 요소를 계산함.
Stream<Integer> evenStream = Stream.iterate(0, n -> n +2 ); // 0, 2, 4, .....
- generate()는 seed를 사용하지 않는다.
Stream<Double> randomStream = Stream.generate(Math::random); // 난수의 값
Stream<Integer> oneStream = Stream.generate(() -> 1); // 1,1,1,1,1,1,1,...
스트림 만들기 - 파일과 빈 스트림
//파일을 소스로 하는 스트림
Stream<Path> Files.list(Path dir) // Path는 파일 또는 디렉토리
Stream<String> Files.lines(Path path)
//비어있는 스트림
Stream emptyStream = Stream.empty();
스트림의 연산 - 중간연산
Stream<T> skip(long n) //앞에서부터 n개 건너뛰기
Stream<T> limit(long maxSize)
IntStream intStream = IntStream.rangeClosed(1, 10);
intStream.skip(3).limit(5).forEach(System.out::print); // 4,5,6,7,8
- 스트림 요소 걸러내기 filter(), distinct()
IntStream intStream = IntStream.of(1,2,2,3,3,4,5,6);
intStream.distinct(),forEach(System.out::print); // 1,2,3,4,5,6
IntStream intStream = IntStrea.rangeClosed(1,10);
intStream.filter(i->i%2==0).forEach(System.out::print); // 2,4,6,8,10
- 스트림 정렬하기 - sorted()
- Comparator의 comparing()으로 정렬 기준을 제공
- 추가 정렬 기준을 제공할 때는 thenComparing()을 사용