[모던 자바 인 액션] - 스트림 활용

김성혁·2022년 3월 27일
0

모던 자바 인 액션

목록 보기
5/7
post-thumbnail

👨🏻‍💻 필터링

  • 스트림의 요소를 선택하는 방법

프레디케이트로 필터링

  • 프레디케이트(불리언을 반환하는 함수)를 인수로 받아서 프레디케이트와 일치하는 모든 요소를 포함하는 스트림을 반환합니다.

고유 요소 필터링

  • 스트림은 고유 요소를 반환하는 distinct 메서드를 지원합니다.
  • 고유 여부는 만든 객체의 hashCode, equals로 결정됩니다.
List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream()
			 .filter(i -> i % 2 == 0)        // 2, 2, 4
			 .distinct()                     // 2, 4
			 .forEach(System.out::println);  // 2, 4

👨🏻‍💻 스트림 슬라이싱

  • 스트림의 요소를 선택하거나 스킵하는 다양한 방법을 설명합니다.

프레이케이트를 이용한 슬라이싱

  • 자바 9은 스트림의 요소를 효과적으로 선택할 수 있도록 takeWhile, dropWhile 두 가지 새로운 메서드를 지원

TAKEWHILE

  • 이미 정렬된 요소를 필터링할 때 takewhile을 이용하면 효과적
  • 무한 스트림을 포함한 모든 스트림에 프레디케이트를 적용해 스트림을 슬라이스할 수 있습니다.
  • 프레디케이트가 false 시 곧바로 반복 작업을 중단합니다.
List<Dish> slicedMenu1 = specialMenu.stream()
								    .takeWhile(dish -> dish.getCalories() < 320 )
									.collect(toList());

DROPWHILE

  • takeWhile과 정반대의 작업을 수행
  • 프레디케이트가 처음으로 거짓이 되는 지점까지 발견된 요소를 버리고 남은 모든 요소를 반환합니다.

스트림 축소

  • 스트림은 주어진 값 이하의 크기를 갖는 새로운 스트림을 반환하는 limit(n) 메서드를 지원합니다.

요소 건너뛰기

  • 스트림은 처음 n개 요소를 제외한 스트림을 반환하는 skip(n) 메서드를 지원합니다.

👨🏻‍💻 매핑

  • 특정 데이터를 선택하는 기능을 제공
  • 변환(transforming)에 가까운 매핑(mapping)
  • map, flatMap 메서드

스트림 평면화

  • flatMap은 하나의 평면화된 스트림을 반환합니다.
  • 스트림의 각 값을 다른 스트림으로 만든 다음에 모든 스트림을 하나의 스트림으로 연결하는 기능을 수행합니다.

👨🏻‍💻 검색과 매칭

  • 특정 속성이 데이터 집합에 있는지 여부를 검색하는 기능
  • allMatch, anyMatch, noneMatch, findFirst, findAny 등

프레디케이트가 적어도 한 요소와 일치하는지 확인

  • anyMatch

스트림의 모든 요소가 주어진 프레디케이트와 일치하는지 검사

  • allMatch

스트림의 모든 요소가 주어진 프레디케이트와 일치하는 요소가 없는지 확인

  • noneMatch

현재 스트림에서 임의의 요소를 반환

  • findAny

첫 번째 요소 찾기

  • findFirst()

Optional이란?

  • 값의 존재나 부재 여부를 표현하는 컨테이너 클래스
  • null은 쉽게 에러를 일으킬 수 있으므로 자바 8 라이브러리 설계자는 Optional를 만들었습니다.
  • Optional은 값이 존재하는지 확인하고 값이 없을 때 어떻게 처리할지 강제하는 기능을 제공합니다.

👨🏻‍💻 리듀싱

  • 모든 스트림 요소를 처리해서 값으로 도출하는 것 (스트림의 모든 요소를 소비하는 관점)
  • 애플리케이션의 반복된 패턴을 추상화하기 위해서 등장

reduce 연산

  • 초기값
    • 초기값을 받지 않도록 오버로된 reduce도 존재. 그러나 이 reduce는 Optional 객체를 반환
  • 두 요소를 조합해서 새로운 값을 만드는 BinaryOperator에 의해 스트림이 하나의 값으로 줄어들 때까지 반복해서 조합

👨🏻‍💻 숫자형 스트림

int calories = menu.stream()
				   .map(Dish::getCalories)
    			   .reduce(0, Integer::sum);

위 코드는 박싱 비용이 숨어있다. Integer::sum은 내부적으로 합계를 계산하기 전에 Integer를 기본형으로 언박싱해야 한다.

기본형 특화 스트림

  • 스트림 API 숫자 스트림을 효율적으로 처리할 수 있는 기능을 제공합니다.
  • 오직 박싱 과정에서 일어나는 효율성과 관련 있으며 스트림에 추가 기능을 제공하지는 않습니다.
  • 숫자 스트림으로 매핑
    • mapToInt, mapToDouble, mapToLong
  • 객체 스트림으로 복원
    • boxed
  • 스트림에 요소가 없는 상황
    - OptionalInt, OptionalDouble, OptionalLong

숫자 범위

  • 시작값과 종료값을 포함하지 않는 스트림
    • range
  • 시작값과 종료값을 포함하는 스트림
    - rangeClosed

👨🏻‍💻 스트림 만들기


값으로 스트림 만들기

  • Stream.of

null이 될 수 있는 객체로 스트림 만들기

  • System.getProperty
    - 제공된 키에 대응하는 속성이 없으면 null을 반환합니다.

String homeValue = System.getProperty("home");
Stream<String> homeValueStream = homeValue == null ? Stream.empty() : Stream.of(value);

// Stream.ofNullable 
Stream<String> homeValueStream = Stream.ofNullable(System.getProperty("home"));

// flatMap
Stream<String> values = Stream.of("config", "home", "user")
															.flatMap(key -> Stream.ofNullable(System.getProperty(key)));

배열로 스트림 만들기

  • Arrays.stream

파일로 스트림 만들기

  • 기존에는 finally 블록에서 자원을 닫아야 했지만 Stream 인터페이스는 AutoCloseable 인터페이스를 구현함으로 try 블록 내의 자원은 자동으로 관리된다.

함수로 무한 스트림 만들기

  • Stream.iterate
    • 초기값과 UnaryOperator를 인수로 받습니다.
  • Stream.generate
    • Supplier를 인수로 받습니다.

0개의 댓글