가자공부하러!

모던자바인액션(CH4) - 스트림(1) 본문

공부/Java

모던자바인액션(CH4) - 스트림(1)

오피스엑소더스 2020. 5. 5. 15:10

목차

요약 및 결론
책 내용
외부 반복과 내부 반복


요약 및 결론

스트림은 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소이고 익명클래스 느낌으로 1회만 사용가능


책 내용

  1. 스트림이란 무엇인가?

    • 컬렉션의 한계 : 컬렉션의 데이터 처리를 위해서는 기능구현을 명시해야하며 병렬처리가 복잡하다.
    • 스트림은 컬렉션을 더 멋지고 더 잘 사용할 수 있게끔 해주는 기능이다.
      • 컬렉션의 주제는 '데이터'이고 스트림의 주제는 '계산'이다.
    • 장점
      • 선언형(질의형)으로 컬렉션 데이터 처리할 수 있다.
      • 데이터를 투명하게 병렬처리할 수 있다.
    • 정의 : 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소
    • 특징 : 파이프 라이닝, 내부 반복
      • 파이프 라이닝 : 대부분의 스트림 연산은 스트림 연산끼리 연결해서 커다란 파이프라인을 구성할 수 있도록 스트림 자신을 반환한다.
      • 내부 반복 : 묵시적으로 반복
  2. 스트림 시작하기

    • 컬렉션 스트림 : 자바 8 컬렉션에는 스트림을 반환하는 stream 메소드가 추가됐으므로 이를 이용한다.
  3. 스트림과 컬렉션

    • 컬렉션과 스트림의 차이

      컬렉션 스트림
      모든 요소는 컬렉션에 추가하기 전에 계산되어 있어야 한다. 요청할 때만 요소를 계산하는 고정된 자료구조이다.
      외부 반복 내부 반복
      여러 번 접근 가능 한 번 탐색된 스트림의 요소는 소비되므로 단 한번만 탐색할 수 있다.
  4. 스트림 연산

    • 중간연산과 최종연산으로 나뉨
      • 왜 스트림의 연산을 두가지로 구분하는 것일까?
        • 중간연산을 합친 다음에 합쳐진 중간 연산을 최종 연산으로 한 번에 처리하기 때문
    • 중간연산 : 각각의 중간 연산은 다른 스트림을 반환하기 때문에 연결하여 질의를 만든다.
      • 서로 다른 중간연산을 한 과정으로 병합하는 루프퓨전 과정이 발생할 수 있다.
    • 최종연산 : 스트림 파이프라인에서 결과를 도출하며 스트림 이외의 결과가 반환된다.
    • 스트림 이용 과정 : 데이터 소스 선택 -> 중간연산 연결(파이프라인) -> 최종연산을 통해 파이프라인을 실행하고 결과 도출

외부 반복 vs 내부 반복

filter메소드 내부에는 분명 요소 하나하나씩 접근하는 반복 로직이 있을텐데 명시적으로 구현되어있지 않기 때문에 내부 반복이라 추측할 수 있다.

내부반복의 장점?

- 스레드간의 공유자원에 대한 동기화 처리를 관리할 필요가 없다.
- 반복자(for, while)를 명시할 필요가 없다.

@Test
void externalLoopTest() {
  List<String> highCaloricDishes = new ArrayList<>();
  Iterator<Dish> iterator = menu.iterator();
  while (iterator.hasNext()) {
    Dish dish = iterator.next();
    if (dish.getCalories() > 300) {
      highCaloricDishes.add(dish.getName());
    }
  }

  log.debug("highCaloricDishes : {}", highCaloricDishes);
  log.debug("highCaloricDishes size : {}", highCaloricDishes.size());
}

@Test
void innerLoopTest() {
  List<String> highCaloricDishes = menu.stream()
      .filter(dish -> dish.getCalories() > 300)
      .map(Dish::getName)
      .collect(Collectors.toList());

  log.debug("highCaloricDishes : {}", highCaloricDishes);
  log.debug("highCaloricDishes size : {}", highCaloricDishes.size());
}
Comments