> For the complete documentation index, see [llms.txt](https://incheol-jung.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://incheol-jung.gitbook.io/docs/study/effective-java/undefined-5/47.md).

# 아이템47 반환 타입으로는 스트림보다 컬렉션이 낫다

원소 시퀀스, 즉 일련의 원소를 반환하는 메서드는 수없이 많다.

* Collection
* Set
* List
* Iterable
* Array

`for-each` 문에서만 쓰이거나 반환된 원소 시퀀스가 (주로 contains(Object) 같은) 일부 `Collection` 메서드를 구현할 수 없을 때는 `Iterable` 인터페이스를 썼다. 반환 원소들이 기본 타입이거나 성능에 민감한 상황이라면 `배열`을 썼다.

Iterable, Array 사용 예제가 필요하다

`스트림`은 반복(`Iteration`)을 지원하지 않는다. 따라서 `스트림`과 `반복`을 알맞게 조합해야 좋은 코드가 나온다.

사실 `Stream` 인터페이스는 `Iterable` 인터페이스가 정의한 추상 메서드를 전부 포함할 뿐만 아니라, `Iterable` 인터페이스가 정의한 방식대로 동작한다. 그럼에도 `for-each`로 스트림을 반복할 수 없는 까닭은 바로 `Stream`이 `Iterable`을 확장(`extend`)하지 않아서다.

```
public interface Stream<T> extends BaseStream<T, Stream<T>> {

    /**
     * Returns a stream consisting of the elements of this stream that match
     * the given predicate.
     *
```

객체 시퀀스를 반환하는 메서드를 작성하는데, 이 메서드가 오직 스트림 `파이프라인` 에서만 쓰일 걸 안다면 마음 놓고 `스트림`을 반환하게 해주자.

`Collection` 인터페이스는 `Iterable`의 하위 타입이고 `stream` 메서드도 제공하니 `반복`과 `스트림`을 동시에 지원한다. 따라서 원소 시퀀스를 반환하는 `공개 API`의 반환 타입에는 `Collection`이나 그 하위 타입을 쓰는 게 일반적으로 최선이다. **하지만 단지 컬렉션을 반환한다는 이유로 덩치 큰 시퀀스를 메모리에 올려서는 안 된다.**

반환할 `시퀀스`가 크지만 표현을 간결하게 할 수 있다면 `전용 컬렉션`을 구현하는 방안을 검토해보자.

```
public class PowerSet {
	public static final <E> Collection<Set<E>> of(Set<E> s) {
		List<E> src = new ArrayList<>(s);
		if (src.size() > 30)
			throw new IllegalArgumentException(
				"집합에 원소가 너무 많습니다.(최대 30개)".: + s);
		
		return new AbstractList<Set<E>>() {
			@Override public int size() {
				// 멱집합의 크기는 2를 원래 집합의 원소 수만큼 거듭제곱과 같다. 
				return 1 << src.size();
			}

			@Override public boolean contains(Object o) {
				return o instanceof Set && src.containsAll((Set)o);
			}

			@Override public Set<E> get(int index) {
				Set<E> result = new HashSet<>();
				for (int i = 0; index != 0; i++, index >>=1)
					if ((index & 1) == 1)
						result.add(src.get(i));
					return result;
			}
		};
	}
}
```

`AbstractCollection`을 활용해서 `Collection` 구현체를 작성할 때는 `Iterable`용 메서드 외에 2개만 더 구현하면 된다. 바로 `contains`와 `size`다.

스트림을 반환하는 두 가지 구현을 알아봤는데 모두 쓸만은 하다. 하지만 반복을 사용하는 게 더 자연스러운 상황에서도 사용자는 그냥 `스트림`을 쓰거나 `Stream`을 `Iterable`로 변환해주는 어댑터를 이용해야 한다. 하지만 이러한 `어댑터`는 클라이언트 코드를 어수선하게 만들고 2,3배가 더 느리다.

### 정리

`원소 시퀀스`를 반환하는 메서드를 작성할 때는, 이를 `스트림`으로 처리하기를 원하는 사용자와 `반복`으로 처리하길 원하는 사용자가 모두 있을 수 있음을 떠올리고, **양쪽을 다 만족시키려 노력하자.** 컬렉션을 반환할 수 있다면 그렇게 하라. 반환 전부터 이미 원소들을 컬렉션에 담아 관리하고 있거나 컬렉션을 하나 더 만들어도 될 정도로 원소 개수가 적다면 `ArrayList` 같은 표준 컬렉션에 담아 반환하라. 그렇지 않으면 전용 컬렉션을 구현할지 고민하라. 컬렉션을 반환하는 게 불가능하면 `스트림`과 `Iterable` 중 더 자연스러운 것을 반환하라. 만약 나중에 `Stream` 인터페이스가 `Iterable`을 지원하도록 자바가 수정된다면, 그때는 안심하고 스트림을 반환하면 될 것이다(`스트림 처리`와 `반복` 모두에 사용할 수 있으니)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://incheol-jung.gitbook.io/docs/study/effective-java/undefined-5/47.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
