[JAVA]스트림
카테고리: JAVA
[29] 스트림
29.1. 스트림 (Stream)
- data의 흐름
- 컬렉션(Collection) 형태로 구성된 데이터를 람다를 이용해 간결하고 직관적으로 프로세스하게 해줌
- 배열, 컬렉션을 대상으로 연산을 수행
- 일관성 있는 연산으로 자료의 처리를 쉽고 간단하게 함
- for, while 등을 이용하던 기존 loop을 대체
- 손쉽게 병렬 처리를 할 수 있게 해줌
29.2. 스트림 특징
- 한번 생성하고 사용한 스트림은 재사용 할 수 없음
- 자료에 대한 스트림을 생성하여 연산을 수행하면 스트림은 소모됨
- 다른 연산을 수행하기 위해서는 스트림을 다시 생성해야 함
- 스트림 연산은 기존 자료를 변경하지 않음
- 자료에 대한 스트림을 생성하면 스트림이 사용하는 사용하는 메모리 공간은 별도로 생성되므로 연산이 수행되어도 기존 자료에 대한 변경은 발행하지 않음
- 스트림 연산은 중간 연산과 최종 연산으로 구분 됨
- 스트림에 대해 중간 연산은 여러 개의 적용 될 수 있지만 최종 연산은 마지막에 한 번만 적용됨
- 최종 연산이 호출되어야 중간 연산에 대한 수행이 이루어지고 그 결과가 만들어짐
- 지연 연산
- 중간 연산에 대한 결과를 연산 중에 알 수 없음
29.3. 스트림 생성
- 컬렉션으로부터 스트림 얻기
- 컬렉션으로는 주로 List를 쓰는데 리스트를 정의하고, 내장된 메소드인 stream()을 이용하게 된다.
ex) Stream<member>stream = memberList.Stream();
- 정의한 stream을 이용해 여러 중간 처리나 최종 처리 작업을 하면 된다. 또, 여기서 memberList.stream()과 같이 처음 얻어온 스트림을 오리지널 스트림이라고 한다.
- 컬렉션으로는 주로 List를 쓰는데 리스트를 정의하고, 내장된 메소드인 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()
- 데이터가 순서대로 정렬된 스트림을 리턴
- filter(), map(), sorted() 등
- 최종 연산이 호출될 때 중간 연산이 수행되고 결과가 생성 됨
- 중간 연산과 최종 연산에 대한 구현은 람다식을 활용함
- 최종 연산
- forEach(), count(), sum() 등
- 스트림이 관리하는 자료를 하나씩 소모해가며 연산이 수행 됨
- 최종 연산 후에 스트림은 더 이상 다른 연산을 적용할 수 없음
- 여러가지 중간 처리를 이어붙이는 것이 가능
- Source(컬렉션, 배열) => 중간처리 => 종결 처리
댓글 남기기