[Java] Stream 개념

지니🧸·2023년 4월 7일
0

Java

목록 보기
1/13

🎞️ Stream, 스트림

자바 8 API에 새로 추가된 기능

  • 선언형: 간결하고 가독성 좋음
  • 조립 가능: 복잡한 데이터 처리도 파이프라인으로 연결
  • 병령화: 멀티스레드 코드를 구현하지 않아도 데이터를 투명하게 병렬 처리 가능. 성능이 좋아짐
List<String> lowCaloricDishesName = 
			menu.stream()
				.filter(d -> d.getCalories() < 400) // 400칼로리 이하만 선택
                .sorted(comparing(Dish::getCalories)) // 칼로리로 정렬
                .limit(5) // 선착순 5개만 선택
                .map(Dish::getName) // 요리명 추출
                .collect(toList()); // 리스트로 저장

위 코드를 멀티코어 아키텍쳐에서 병렬로 실행 가능한 코드로 만들려면 stream() 대신 parallelStream()을 사용하면 된다

🎞️ 스트림이란?

스트림: 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소

  • 파이프라이닝: 대부분의 스트림 연산은 스트림 연산끼리 연결해서 커다란 파이프라인을 구성할 수 있도록 스트림 자신을 반환함
    • 데이터베이스의 질의와 비슷
  • 내부 반복

🎞️ 스트림 연산

  • filter: 람다를 인수로 받아 스트림에서 특정 요소를 제외 시킴
    • .filter(dish -> dishg.etCalories() > 300)
  • map: 람다를 이용해 한 요소를 다른 요소로 변환하거나 정보를 추출함
    • .map(Dish::getName)
  • limit: 정해진 개수 이상의 요소가 스트림에 저장되지 못하게 스트림 크기를 축소함
  • collect: 스트림을 다른 형식으로 변환
    • .collect(toList())

🎞️ 스트림 vs. 컬렉션

컬렉션: 현재 자료구조가 포함하는 모든 값을 메모리에 저장하는 자료구조

  • 컬렉션의 모든 요소는 컬렉션에 추가하기 전에 계산해야 함
  • eager 계산

스트림: 요청할 때만 요소를 계산하는 고정된 자료구조

  • 스트림에 요소를 추가하거나 스트림에서 요소를 제거할 수 없음
  • 사용자가 데이터를 요청할 때만 값을 계산
  • lazy 계산

🎞️ 외부 반복과 내부 반복

외부 반복(컬렉션): 사용자가 직접 요소를 반복해야 함 (예) for loop

  • 병렬성을 스스로 관리해야 함 (병렬성을 포기하거나 synchronized 사용)

내부 반복(스트림): 반복을 알아서 처리하고 결과 스트림값을 어딘가에 저장함

🎞️ 중간 연산과 최종 연산

중간 연산: 연결할 수 있는 스트림 연산

  • 다른 스트림을 반환함
  • 게으름
연산반환 형식연산의 인수함수 디스크립터
filterStream<T>Predicate<T>T -> boolean
mapStream<R>Function<T, R>T -> R
limitStream<T>
sortedStream<T>Comparator<T>(T, T) -> int
distinctStream<T>

최종 연산: 스트림을 닫는 연산

  • 스트림 파이프라인에서 결과를 도출함
연산반환 형식목적
forEachvoid스트림의 각 요소를 소비하면서 람다 적용
countlong스트림의 요소 개수 반환
collect스트림을 리듀스해서 리스트/맵/정수 형식의 컬렉션을 만듬

참고: Modern Java in Action (라울-게이브리얼 등 지음)

profile
우당탕탕

0개의 댓글