JAVA Stream API에 대한 정리

Stream은 자바 8부터 도입된 모던 자바 API로 함수형(함수를 변수처럼 전달함) 프로그래밍을 제공한다.

스트림은 생성 -> 중간연산 -> 최종연산(일종의 출력)으로 구성되어있다. 따라서 최종연산을 하지 않을 경우엔 스트림으로 가공한 데이터 소스(컬렉션, 배열 등)을 리턴받을 수 없다. 또한 스트림은 한 번 사용하는 것으로 설계되었기 때문에 한 번 terminal 연산이 호출되면 스트림은 consumed되고 다시 사용할 수 없다.

 

 

사전지식 - 제네릭에 대하여

Stream API에는 아래와 같은 형식이 자주 등장한다. 

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

 

? super T : T이거나 T의 부모 클래스 중 하나. 주로 데이터를 소비할 때(consume) 사용한다.

? extends R : R이거나 R을 상속받은 자식 중 하나. 주로 데이터를 생성할 때(produce) 사용한다.

여기서 T,R은 지금 다루고 있는 데이터 타입을 의미한다.( ex, String, Integer)

 

Predicate, Function, FlatMap 함수형 인터페이스의 차이

 

Predicate : 어떤 값을 받아서 true, false를 판단한다.

Function : 어떤 값을 받아서 다른 값(또는 다른 타입)으로 변형한다.

flatmap : 변환(mapping)한 후 데이터를 일렬로 늘어놓는다.

 

flatMap 시그니처를 분석해보면

Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)

 

T를 받아서 Stream인 R로 변환하고 리턴형태는 Stream(R)을 리턴한다는 뜻이다. 

즉, fruits.flatMap(fruit -> Arrays.Stream(fruit.split(",")) 함수는 

fruits의 ","를 제거한 형태를 Arrays의 Stream 형태로 리턴한다는 뜻이다.

 

Reduce : "결과물 박스" 하나를 계속 옆으로 넘기면서 작업을 누적시킨다.

 

// 예: [1, 2, 3] 다 더하기
int sum = IntStream.of(1, 2, 3)
    .reduce(0, (누적된값, 들어온값) -> 누적된값 + 들어온값);

 

 

  1. 초기값 0을 준비합니다. (이게 누적된 값의 시작)
  2. 1이 들어옴 -> 0 + 1 = 1 (이제 누적된 값은 1)
  3. 2가 들어옴 -> 1 + 2 = 3 (이제 누적된 값은 3)
  4. 3이 들어옴 -> 3 + 3 = 6
  5. 최종 결과: 6

즉, reduce(초기값, (쌓인거, 새거) -> 합칠방법) 입니다.

 

 

반응형