요약
•
메서드에서 원소 시퀀스를 반환해야 한다면, 가급적 컬렉션을 반환하자.
스트림과 iteration
•
원소 시퀀스(일련의 원소들)를 반환하는 메서드에서 반환 타입은 Collection, Set, List와 같은 컬렉션 인터페이스와 Iterable, 배열이 사용되었다. 하지만 자바 8부터 스트림이 도입되고 나서 이러한 메서드들의 반환 타입에 스트림이라는 선택지가 생겼다.
•
스트림은 반복(iteration)을 지원하지 않기 때문에, 스트림과 반복을 알맞게 조합해야 좋은 코드를 만들 수 있다.
for (ProcessHandle ph : ProcessHandle.allProcesses()::iterator) {
... // 프로세스 처리
}
Java
복사
•
위 코드는 Stream의 iterator 메서드를 메서드 참조 방식으로 전달했지만, 지저분하고 가독성이 좋지않고 컴파일 오류가 발생한다.
public static <E> Iterable<E> iterableOf(Stream<E> stream) {
return stream::iterator;
}
for (ProcessHandle ph : iterableOf(ProcessHandle.allProcesses())) {
... // 프로세스 처리
}
Java
복사
•
이와 같이 어댑터를 사용하면 모든 스트림을 for-each 문으로 반복할 수 있다.
public static <E> Stream<E> streamOf(Iterable<E> iterable) {
return StreamSupport.stream(iterable.spliterator(), false);
}
Java
복사
•
반대로 위처럼 iterator를 어댑터를 사용하여 스트림의 파이프라인으로 전달하기 할 수 있다.
원소 시퀀스 반환 타입
•
위의 두 어댑터를 통해 스트림 파이프라인에서만 사용된다면 스트림을 반환하고, 반복문에서만 사용된다면 Iterable을 반환하자.
•
Collection 인터페이스는 iterable의 하위 타입이고 stream 메서드를 제공하여 반복과 스트림을 동시에 지원한다.
•
공개 API에 적용하기에는 둘 다 지원을 해야하니, 원소 시퀀스를 반환하는 반환 타입에는 Collection이나 그 하위 타입을 사용하자.
•
하지만 컬렉션을 반환한다는 목적으로 큰 용량의 시퀀스를 메모리에 올리면 안된다. 반환할 시퀀스가 크지만 표현을 간결하게 할 수 있다면, 전용 컬렉션을 구현하여 해결하자.
•
전용 컬렉션을 구현할 때는 가급적 contains와 size를 구현하고, 이를 구현하는게 불가능하다면 컬렉션 보다 스트림이나 Iterable을 반환하는게 낫다.