Java - Stream

iseon_u·2022년 6월 11일
0

Java

목록 보기
70/77
post-thumbnail

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); // 0,2,4,6, ...
Stream<Double> randomStream = Stream.generate(Math::random); // 람다식
IntStream intStream = new Random().ints(5); // 난수 스트림 (크기가 5)

스트림 작업 순서

stream.distinct().limit(5).sorted().forEach(System.out::println)
// 중간 연산 - distinct() limit(5) sorted()
// 최종 연산 - forEach(System.out::println)
  1. 스트림 만들기
  2. 중간 연산 (0번 ~ n번)
    • 연산 결과가 스트림인 연산
    • 반복적으로 적용 가능
  3. 최종 연산 (결과 - 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(); // list 를 스트림으로 변환

// 스트림의 모든 요소를 출력
intStream.forEach(System.out::print); // 12345
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); // 5개의 요소만 출력

IntStream intStream = new Random().ints(5); // 크기가 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); // 1, 2, 3, 4
IntStream intStream = IntStream.rangeClosed(1, 5); // 1, 2, 3, 4, 5
  • 특정 범위의 정수를 요소로 갖는 스트림 생성하기
  • rangeClosed() 는 범위 끝 포함

스트림 만들기 - 람다식 iterate(), generate()

  • 람다식을 소스로 하는 스트림 생성하기
Stream<Integer> evenStream = Stream.iterate(0, n->n+2); // 0, 2, 4, 6, ...
  • 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(); // empty() 는 빈 스트림을 생성해서 반환
long count = emptyStream.count(); // count 의 값은 0
  • 비어 있는 스트림 생성하기
profile
🧑🏻‍💻 Hello World!

0개의 댓글