• Stream이란?

 

A sequence of elements supporting sequential and parallel aggregate operations

순차, 병렬 집계 작업을 지원하는 요소

 

컬렉션, 배열 등의 저장 요소를 하나씩 참조하여 반복적으로 처리할 수 있도록 해주는 인터페이스

데이터소스를 추상화하고, 데이터를 다루는데 자주 사용되는 메서드들이 정의되어 있습니다.

간단하게 병렬 처리가 가능하여 많은 요소들을 빠르게 처리할 수 있습니다. 

 

* 추상화 -> 어떤 데이터든 같은 방식으로 다룰 수 있게 하는 것, 재사용성이 높아짐

 

 

자바8 이전에는 컬렉션, 배열 인스턴스의 데이터를 for, if 문을 통해 처리했습니다.

이러한 경우 로직이 복잡해질수록 코드의 가독성이 떨어지게 됩니다.

순회를 위한 for문, 필터링을 위한 if문 등의 소스코드를 스트림을 사용하면 간단하게 한 줄로 구현할 수 있습니다.

 

 

 

  • Stream의 특징

 

- 데이터 구조가 아니라 컬렉션, 배열 등에서 입력을 받습니다. (선언)

- 다양한 중간 작업을 파이프라인 할 수 있습니다. (가공)

- 기존 데이터를 변경하지 않고 파이프 라인 방식에 따른 결과를 제공합니다. (결과)

 

 

 

  • Stream 사용하기

 

Stream은 데이터의 흐름입니다.

컬렉션, 배열 인스턴스에 함수 여러 개를 조합하여 원하는 결과를 필터링하고 가공할 수 있습니다.

람다를 이용하여 컬렉션과 배열을 함수형으로 처리할 수도 있습니다.

 

 

 

우선, Stream을 사용하는 방법에 대해 알아보겠습니다.

 

스트림의 구조는 선언, 가공, 결과로 나뉘어 있습니다. 

 

 

1. 선언

Stream<DataType> StreamName = Arrays.stream(ArrayName);
Stream<DataType> StreamName = ListName.stream();

...

Arrays.stream(ArrayName).Intermediate Operations ......

컬렉션, 배열 등을 스트림 형태로 만듭니다.

중간 연산(가공 메서드)을 바로 붙여서 사용할 수도 있습니다.

 

 

2. 가공(중간 연산)

 

Lazy Invocation

중간 연산은 실행하지 않고 있다가 forEach와 같은 최종연산이 적용될 때 실행됩니다.

 

 

 - Map: 주어진 함수를 스트림의 요소에 적용한 결과를 반환

List number = Arrays.asList(2,3,4,5);
List square = number.stream().map(x->x*x).collect(Collectors.toList());

 

- Filter: 스트림 내의 요소들을 인자로 전달 된 조건에 따라 선택

List names = Arrays.asList("Reflection","Collection","Stream");
List result = names.stream().filter(s->s.startsWith("S")).collect(Collectors.toList());

 

- Sorted: 스트림 정렬

List names = Arrays.asList("Reflection","Collection","Stream");
List result = names.stream().sorted().collect(Collectors.toList());

 

 

3. 결과 (최종 연산)

 

 - collect: 스트림의 값을 다시 컬렉션으로 변환

List number = Arrays.asList(2,3,4,5,3);
Set square = number.stream().map(x->x*x).collect(Collectors.toSet());

 

 - forEach: 스트림의 모든 요소를 반복

List number = Arrays.asList(2,3,4,5);
number.stream().map(x->x*x).forEach(y->System.out.println(y));

 

 - reduce: 값을 누적으로 계산, BinaryOperator를 파라미터로 받습니다.

List number = Arrays.asList(2,3,4,5);
int even = number.stream().filter(x->x%2==0).reduce(0,(ans,i)-> ans+i);


// 잘 이해 안가서 추후에 https://futurecreator.github.io/2018/08/26/java-8-streams/ 참고

 

 

 

위 내용을 바탕으로 Stream이 자주 사용되는 예시에 대해 알아보겠습니다.

 

 

1. Empty Collection

// 빈 stream 생성하기
Stream<String> streamEmpty = Stream.empty();
public Stream<String> streamOf(List<String> list) {
    return list == null || list.isEmpty() ? Stream.empty() : list.stream();
}

 

요소가 없는 스트림인 경우 null 값이 리턴되는 상황을 피하고자 할 때 위와 같이 empty() 메서드를 사용합니다.

 

 

 

2. Stream of Collection ( Collection, List, Set )

Collection<String> collection = Arrays.asList("a", "b", "c");
Stream<String> streamOfCollection = collection.stream();

 

 

3. Stream of Array

Stream<String> streamOfArray = Stream.of("a", "b", "c");

String[] arr = new String[]{"a", "b", "c"};
Stream<String> streamOfArrayFull = Arrays.stream(arr);
Stream<String> streamOfArrayPart = Arrays.stream(arr, 1, 3); // 배열 일부분만

 

 

4. Stream.builder()

// 참고1: 빌더를 사용할 때 타입을 지정하지 않으면 Object 인스턴스가 생성 됨
// 참고2: 자바 빌더 패턴

Stream<String> streamBuilder =
  Stream.<String>builder().add("a").add("b").add("c").build();
  

 

 

5. Stream.iterate()

Stream<Integer> streamIterated = Stream.iterate(40, n -> n + 2).limit(20);

 

 

6. Parallel Streams

Stream<Product> streamOfCollection = productList.parallelStream(); // 병렬 스트림 생성
boolean isParallel = streamOfCollection.isParallel(); // 병렬 여부 확인
boolean bigPrice = streamOfCollection
  .map(product -> product.getPrice() * 12)
  .anyMatch(price -> price > 200);

Java8에서부터는 parallelStream() 메서드를 사용하여 간단하게 병렬처리를 할 수 있습니다.

 

// 컬렉션이나 배열이 아닌 경우
IntStream intStreamParallel = IntStream.range(1, 150).parallel();
boolean isParallel = intStreamParallel.isParallel();

컬렉션이나 배열이 아닌 경우 parallel() 메서드를 사용합니다.

 

// back to the sequential
IntStream intStreamSequential = intStreamParallel.sequential();
boolean isParallel = intStreamSequential.isParallel();

sequential() 메서드를 사용해 순차적으로 다시 돌아갈 수 있습니다.

 

 

 

 

[ 참고 ]

 

https://www.geeksforgeeks.org/stream-in-java/

https://www.baeldung.com/java-8-streams

 

복사했습니다!