> For the complete documentation index, see [llms.txt](https://develop-footprint.gitbook.io/o/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://develop-footprint.gitbook.io/o/java/effective-java/7/item-46.md).

# item 46) 스트림에서는 부작용 없는 함수를 사용하라

## 스트림 패러다임

* 함수형 프로그래밍에 기초한 패러다임
* 스트림이 제공하는 표현력, 속도, 병렬성을 얻기 위해서 스트림 API와 스트림 패러다임을 받아들여야 한다.
* 계산을 일련의 변환으로 재구성하는 것이 핵심
* 각 변환 단계는 가능한 한 이전 단계의 결과를 받아 처리 하는 순수 함수여야 한다.

> 순수 함수: 입력만이 결과에 영향을 주는 함수, 다른 가변 상태를 참조하지 않고, 함수 스스로도 다른 상태를 변경하지 않는다.

## forEach의 용도

* forEach 연산은 **스트림 계산 결과를 보여줄 때만 사용**한다.
* forEach 내부에서 연산 작업을 수행할 경우 스트림 코드를 가장한 반복적 코드가 되버릴 수 있다. 스트림 API의 이점을 살리지 못하여 같은 기능의 반복 코드 보다 길고, 읽기 어렵고 유지보수에도 안좋다.

## Collectors

* 축소 전략을 캡슐화한 블랙박스 객체: 스트림의 원소들을 하나의 객체(보통은 컬렉션 객체)로 취합한다.
* **toList, toSet, toCollection** 메서드를 사용해 컬렉션 타입을 반환할 수 있으며, 정적 임포트하여 사용 시 가독성이 좋아진다.

```php
List<String> topTen = freq.keySet().stream()
    .sorted(comparing(freq::get).reversed())
    .limit(10)
    .collect(toList());
```

* comparing 메서드를 사용해 키 추출 함수 get을 입력받아 value를 비교해 역순으로 저장한다.

## **toMap 메서드**

* (스트림 원소를 키에 매핑하는 함수,스트림 원소를 값에 매핑하는 함수, 병합 함수) 세가지를 인수로 받아 맵 형식으로 반환한다.

> 병합 함수

* 어떤 키와 그 키에 연관된 원소 중 하나를 골라 연관 짓는 맵을 만들 때 유용하다.
* 아래는 다양한 음악가의 앨범들을 담은 스트림에서 (음악가, 음악가의 베스트 앨범) 맵을 생성하는 예제이다.

```php
Map<Artist, Album> topHits = albums.collect(
	toMap(Album::artist, a->a, maxBy(comparing(Album::sales))));
```

* 아래는 마지막에 들어온 값을 키에 저장하도록 병합 함수를 지정한 예제이다.

```coffeescript
toMap(KeyMapper, valueMapper, (oldVal, newVal) -> newVal)
```

## **groupingBy 메서드**

* gropingBy(분류함수, 맵 팩토리, 다운스트림 수집기) 형태이다.
* 분류 함수를 입력받아, (카테고리, 카테고리에 속하는 원소들의 리스트) 형태의 맵을 담은 수집기를 반환한다.

> 분류 함수: 입력받은 원소가 속하는 카테고리 반환

* 키에 대해 리스트 외의 값을 갖도록 하려면, 다운스트림 수집기를 명시해야 한다.

> 다운스트림 수집기

* 맵 팩토리를 지정할 수 있다.

## **minBy, maxBy 메서드**

* 인수로 받은 비교자를 이용해 스트림에서 가장 값이 작거나 가장 값이 큰 원소를 찾아 반환한다.
* 수집과는 관련이 없지만 Collections에 정의되어 있다.

## **joining 메서드**

* joining(구분문자, 접두문자, 접미문자)
* 원소들을 concat하는 수집기를 반환
* CharSequence 인스턴스의 스트림에만 적용 가능
