Stream
title: 2025-08-21 author: 강병호 (이름) date: 2025-08-21 (날짜) category: TIL/강병호/2025/08 (파일 경로 : TIL/{이름}/{연}/{월}) layout: post (자유) —
5.3 매핑
특정 객체에서 특정 데이터를 선택하는 작업으로 스트림 API의 map
, flatMap
메서드가 존재한다.
스트림의 각 요소에 함수 적용
함수를 인수로 받는 방식으로 map
메서드를 지원한다.
인수로 제공된 함수의 경우 각 요소에 적용되며 함수에 적용한결과가 새로운 요소가 된다.
```
List<String> dishNames = menu.stream()
.map(Dish::getName)
.map(Dish::length)
.collect(toList());
```
스트림 평면화
리스트에서 고유 문자로 이루어진 리스트를 반환하는 방법으로 flatMap
의 메서드가 존재한다.
[!distinct 이용]
words.stream() .map(word -> word.split("")) .distinct() .collect(toList());
위와 같은 방식으로 처리하게 되면
map
으로 전달한 람다가 각 단어의 String을 반환하는 문제가 존재한다. 즉, 원하는 결과는Stream<String>
인 반면Stream<String[]>
이 된다는 것이다.
```
List<String> uniqueCharacters = words.stream()
.map(word -> word.split(""))
.flatMap(Arrays::stream) // 생성된 스트림 하나의 스트림으로 평면화
.distinct()
.collect(toList());
```
해당 과정에서 flatMap
은 각 배열을 스트림이 아니라 스트림의 콘텐츠로 매핑한다. 즉, map(Arrays::stream)과 달리 flatMap
은 하나의 평면화된 스트림을 반환하는 것이다.
map -> flatMap : Stream<String[]> -> Stream<String>
이렇게 반환되는 결과의 최종 형태는 List<String>
이다.
결국 flatMap
메서드는 스트림의 각 값을 다른 스트림으로 만든 다음에 모든 스트림을 하의 스트림으로 연결한다.
5.3 검색과 매칭
특정 속성이 데이터 집합에 존재하는 여부를 처리하기 위해 사용된다.
프레디케이트가 적어도 한 요소와 일치하는지 확인
주어진 스트림에서 적어도 한 요소와 일치하는지 확인하기 위해 사용하는 경우로 anyMatch
메서드를 사용한다.
```
if (menu.stream().anyMatch(Dish::isVegetarian)) {
System.out.println("The menu is (somewhat) vegetarian friendly!!);
}
```
프레디케이트가 모든 요소와 일치하는지 검사
스트림의 모든 요소가 주어진 프레디케이트와 일치하는 지 검사하기 위해 사용하는 경우로 allMatch
메서드가 존재한다.
```
boolean isHealthy = menu.stream()
.allMatch(dish -. dish.getCaloreis() < 1000);
```
Nonematch
noneMatch
의 경우 주어진 프레디케이트와 일치하는 요소가 없는지 확인한다.
```
boolean isHealthy = menu.stream()
.noneMatch(d -> d.getCaloreis() >= 1000);
```
위의 세 메서드(anyMatch
, allMatch
, noneMatch
)는 스트림 쇼트서킷 기법을 사용한다.
[!쇼트서킷 평가] > 전체 스트림을 처리하지 않았더라도 결과를 반환할 수 있는 경우가 존재한다.
allMatch
,noneMatch
,findFirst
, 등의 연산은 모든 스트림의 요소를 처리하지 않고도 결과를 반환하는 쇼트서킷의상황에서도 작동한다.
요소 검색
현재 스트림에서 임의의 요소를 반환한다.
findAny
메서드를 주로 사용하며 다른 스트림 연산과 연결해서 사용가능하다.
```
Optinal<Dish> dish = menu.stream()
.filter(Dish::isVegetarian)
.findAny();
``` 해당 경우 내부적으로 단일 과정으로 실행할 수 있도록 최적화하는 즉, 쇼트 서킷을 이용해 결과를 찾는 즉시 실행을 종료한다.
첫 번째 요소 찾기
일부 스트림에는 이미 논리적인 순서가 정해져있을 수 잇다. 이 경우 첫 번째 요소를 찾기 위해 findFirst
메서드를 사용한다.
```
List<Integer> someNumbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> firstSquareDivisiableByThree = someNumbers.stream()
.map(n -> n * n)
.filter(n -> n % 3 == 0)
.findFirst(); // 9
```