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
```

results matching ""

    No results matching ""