[JAVA]스트림

Date:     Updated:

카테고리:

태그:

[29] 스트림

29.1. 스트림 (Stream)

  • data의 흐름
  • 컬렉션(Collection) 형태로 구성된 데이터를 람다를 이용해 간결하고 직관적으로 프로세스하게 해줌
    • 배열, 컬렉션을 대상으로 연산을 수행
    • 일관성 있는 연산으로 자료의 처리를 쉽고 간단하게 함
  • for, while 등을 이용하던 기존 loop을 대체
  • 손쉽게 병렬 처리를 할 수 있게 해줌

29.2. 스트림 특징

  • 한번 생성하고 사용한 스트림은 재사용 할 수 없음
    • 자료에 대한 스트림을 생성하여 연산을 수행하면 스트림은 소모됨
    • 다른 연산을 수행하기 위해서는 스트림을 다시 생성해야 함
  • 스트림 연산은 기존 자료를 변경하지 않음
    • 자료에 대한 스트림을 생성하면 스트림이 사용하는 사용하는 메모리 공간은 별도로 생성되므로 연산이 수행되어도 기존 자료에 대한 변경은 발행하지 않음
  • 스트림 연산은 중간 연산과 최종 연산으로 구분 됨
    • 스트림에 대해 중간 연산은 여러 개의 적용 될 수 있지만 최종 연산은 마지막에 한 번만 적용됨
    • 최종 연산이 호출되어야 중간 연산에 대한 수행이 이루어지고 그 결과가 만들어짐
      • 지연 연산
      • 중간 연산에 대한 결과를 연산 중에 알 수 없음

29.3. 스트림 생성

  • 컬렉션으로부터 스트림 얻기
    • 컬렉션으로는 주로 List를 쓰는데 리스트를 정의하고, 내장된 메소드인 stream()을 이용하게 된다.
      ex)
      Stream<member>stream = memberList.Stream();
      
    • 정의한 stream을 이용해 여러 중간 처리나 최종 처리 작업을 하면 된다. 또, 여기서 memberList.stream()과 같이 처음 얻어온 스트림을 오리지널 스트림이라고 한다.
  • 배열로부터 스트림 얻기
    • 배열로부터 스트림을 얻는 방법은 컬렉션에서 스트림을 얻는 것과 비슷함. 회원의 이름을 저장하는 mArr가 있다고 가정하면, 아래와 같이 배열로부터 스트림을 얻을 수 있습니다.
       Stream<String> stream = Stream.of("x", "y", "z");   // 가변 인자
       IntStream stream = IntStream.of(1, 2, 3);           // 가변 인자
       Stream<String> stream = Arrays.stream(mArr);
      
    • Stream.of()메서드를 통하여 원하는 값을 넣음으로써 스트림을 생성할 수 있다.
    • Arrays.stream()메서드를 이용하여 스트림을 얻어올 수 있다.
  • 숫자 범위로부터 스트림 얻기
    • 일정 숫자의 범위를 가지는 스트림을 얻을 때, range()rangeClosed()메서드를 사용한다.
      ex 1)
      IntStream stream = IntStream.rangeClosed(x, y)
      
      ex 2)
      IntStream stream = IntStream.range(x, y)
      
    • ex 1)로 가져올 경우, x부터 y까지이지만, ex 2)로 가져올 경우에는 x부터 y-1까지이다. 이 말은 즉, (x, y) = (1, 5)라면 ex 1)1, 2, 3, 4, 5를, ex 2)라면 1, 2, 3, 4를 얻는다.
  • 빈 스트림 얻기
    • 값이 없는 스트림을 선언해놓을 때 사용합니다.
      Stream<String> stream = Stream.empty();
      
  • 람다식으로 스트림 생성하기 - generate()
    • generate()의 인자는 함수를 받고, 이 함수를 통해 리턴되어진 객체들을 요소로 갖게되는 Stream을 생성한다.
      ex 1)
      Stream<String> stream = Stream.generate(() -> "A").limit(10);
      
      ex 2)
      Random random = new Random();
      IntStream.generate(() -> random.nextInt(45) + 1).limit(6);
      
    • ex 1)경우에는 A가 10개 출력되고, ex 2)경우에는 로또 난수가 출력이 됩니다. 로또 난수를 예를 든 이유는 혹시 모르지 않습니까 내 컴퓨터가 1등을 만들어 줄 수도(?)
  • 람다식으로 스트림 생성하기 - iterate()
    • genarate()와 유사하지만, iterate()는 두 개의 인자 값을 받는다. 첫 번째 인자는 초기값이며, 두 번째 인자는 함수이다. 하지만, 첫번째 인자 값은 선택이다.
      Stream<Integer> stream = Stream.iterate(0, n -> n + 1).limit(5);
      
    • 주의 : limit()을 해주지 않는다면 제한이 걸리지 않아 제한없이 계속 할당된다.

29.4. 스트림 중간 연산, 최종 연산

  • 중간 연산
    • filter(), map(), sorted() 등
      • 조건에 맞는 요소를 추출(filter)하거나 요소를 변환함(map)
      • filter()
        • 만족하는 데이터만 걸러내는데 사용
      • map()
        • 데이터를 변형하는데 사용
        • 데이터에 해당 함수가 적용된 결과물을 제공하는 스트림을 리턴
      • sort()
        • 데이터가 순서대로 정렬된 스트림을 리턴
  • 최종 연산이 호출될 때 중간 연산이 수행되고 결과가 생성 됨
  • 중간 연산과 최종 연산에 대한 구현은 람다식을 활용함
  • 최종 연산
    • forEach(), count(), sum() 등
  • 스트림이 관리하는 자료를 하나씩 소모해가며 연산이 수행 됨
  • 최종 연산 후에 스트림은 더 이상 다른 연산을 적용할 수 없음
  • 여러가지 중간 처리를 이어붙이는 것이 가능
    • Source(컬렉션, 배열) => 중간처리 => 종결 처리

JAVA 카테고리 내 다른 글 보러가기

댓글 남기기