Java / / 2023. 2. 3. 16:52

스트림(Stream)과 스트림의 특징

반응형

 

💡 스트림(Stream)

  • 데이터의 연속적인 흐름을 뜻한다.
  • 다양한 데이터 소스(Collection - List, Set, Map / Array 등)를 표준화된 방법으로 다루기 위한 것이다.

 

데이터 소스(List, Set, Map, 배열) → Stream(스트림 만들기) → 중간연산s...(N번) → 최종연산(1번)

 

스트림으로 변환하는 방법

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)

 


 

스트림이 제공하는 기능 → 중간 연산 / 최종 연산

중간연산 연산결과가 스트림인 연산. 반복적으로 사용 가능 (N번)
최종연산 연산결과가 스트림이 아닌 연산. 단 한번만 적용 가능 (스트림의 요소를 소모)

 

String[] strArr = {"dd","aaa","CC","cc","b"};

//중간연산
Stream<String> stream = Stream.if(strArr);           //문자열 배열이 소스인 스트림
Stream<String> filteredStream = stream.filter();     //걸러내기
Stream<String> distinctedStream = stream.distinct(); //중복제거
Stream<String> sortedStream = stream.sort();         //정렬
Stream<String> limitedStream = stream.limit(5);      //스트림 자르기

//최종연산
int total = stream.count();                           //요소 개수 세기

 

 

해당 포스팅은 자바의 정석 인터넷 강의를 참고하여 작성한 글입니다.

필요하시다면 자바의 정석 강의나 책을 추가로 참고하셔도 될 것 같습니다 : )

 

 

 


💡 스트림(Stream)의 특징

1. 스트림은 데이터 소스로부터 데이터를 읽기만할 뿐 변경하지는 않는다.

2. 스트림은 Iterator처럼 일회용이다. (필요하면 다시 스트림을 생성해야 함)

  • 최종연산(요소를 소모)을 하고 나면 Stream이 닫힌다.

 

strStream.forEach(System.out::println) //모든 요소를 화면에 출력 (최종연산)
int numberOfStr = strStream.count();   //error. 스트림이 이미 닫혔다.

3. 최종 연산 전까지 중간연산이 수행되지 않는다.  지연된 연산

//로또 번호 출력 로직
IntStream intStream = new Random().ints(1,46); //1~45 범위의 무한 스트림
intStream.distinct().limit(6).sorted()         //중간 연산
	.forEach(i -> System.out.println(i+","));  //최종 연산

 

  • 무한 스트림은 중복 제거가 되지 않는데 위와 같은 코드가 가능한 것일까? Yes
    • distinct().limit(6).sorted()의 연산을 순서대로 바로 수행하는 것이 아니다.
    • 지연된 연산으로 스트림을 가지고 어떤 작업을 해야하는지 체크만 해두고 나중에 필요할 때 수행한다.

4. 스트림은 작업을 내부 반복으로 처리한다.

for(String srt : strList)
	System.out.println(str);
-------------------------------
stream.forEach(System.out::println); //내부 반복(for문을 메서드 안으로 넣음)

5. 스트림의 작업을 병렬로 처리  병렬 스트림

Stream<String> strStream = Stream.of("dd","aaa","CC","cc","b");
int sum = strStream.parallel() //병렬 스트림으로 전환(속성만 변경)
	.mapToInt(s -> s.length()).sum(); //모든 문자열 길이의 합

 

※ paraller() - 병렬처리(빅데이터 작업을 위한 멀티쓰레드 처리)

 

6. 기본형 스트림 IntStream, LongStream, DoubleStream

  • 오토박싱 & 언박싱의 비효율이 제거된다. (Stream<Integer> 대신 IntStream 사용)
    • T는 int같은 기본형이 들어갈 수 없어서, Stream을 만들면 Integer 같은 참조형으로 변환되어 들어간다.(오토박싱)
    • IntStream같은 것을 사용하면 위와 같은 오토박싱 작업에 들어가는 소요 시간을 절약해 준다. (빅데이터 작업)
  • 숫자와 관련된 유용한 메서드를 Stream<T>보다 더 많이 제공
    • Stream<T>에서 T가 숫자인지 아닌지 알 수 없기 때문에 count() 정도만 제공한다.
    • 하지만 count(), sum(), average()등 많은 메서드를 제공한다.

 

※ 작업하는데 시간이 많이 걸리고, 성능을 개선을 하고 싶다는 생각이 들 때면, 기본형 스트림을 사용해 보자!

 

 

 

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유