-
item 47 반환 타입으로는 스트림보다 컬렉션이 낫다책/이펙티브 자바 2022. 4. 12. 17:35
ITEM 47 반환 타입으로는 스트림보다 컬렉션이 낫다
원소 시퀀스(일련의 원소)를 반환하는 메서드는 수없이 많으며 자바 7까지는 이런 메서드의 반환 타입을 Collection, SEt, List 같은 컬렉션 인터페이스나 Iterable이나 배열을 사용했다
- 이 중에서 가장 적합한 타입을 선택하는게 어렵지 않았다
- 컬렉션 인터페이스 : 기본으로 사용
- Iterable 인터페이스 : for-each 문에서만 쓰이거나 반환된 원소 시퀀스가(주로 contains(Object) 같은) 일부 Collection 메서드를 구현할 수 없을때
- 배열 : 반환 원소들이 기본 타입이거나 성능에 민감한 상황
하지만 자바 8이 스트림이라는 개념을 들고 오면서 선택이 복잡해졌다
- 스트림은 반복을 지원하지 않아서 스트림과 반복을 조합해야 좋은 코드가 나온다
- api를 스트림만 반환하도록 만들면 반환된 스트림을 for-each로 반복하기가 힘들다
- 사실 Stream 인터페이스는 Iterable 인터페이스가 정의한 추상 메서드를 전부 포함하며 Iterable 인터페이스가 정의한 방식대로 동작한다
- 하지만 Stream이 Iterable을 확장하지 않아서 for-each로 반복이 불가능하다
- 안타깝지만 이 문제를 해결할 좋은 방법은 없다
- 어댑터를 사용해서 문제를 해결할 수는 있지만 따로 구현을 해야 하며 클라이언트를 어수선하게 만들고 속도도 느려질 수 있다
- 스트림 파이프라인에서만 쓰인다면 스트림을 반환하게 해주고 반환된 객체들이 반복문에서만 쓰인다면 Iterable을 반환시켜주자
- 두개 모두 배려하기에는 코드가 복잡해진다
- Collection 인터페이스는 Iterable의 하위타입이고 stream 메서드도 제공해 반복과 스트림을 동시에 지원한다
- 원소 시퀀스를 반환하는 공개 API의 반환 타입에는 Collection이나 그 하위타입을 쓰는게 보통 최선의 선택이다
- Arrays 역시 Arrays.asList 와 Stream.of 메서드로 손쉽게 반복과 스트림을 지원 가능하다
- 반환하는 시퀀스의 크기가 메모리에 올려도 안전하다면 ArrayList나 HashSet 같은 표준 컬렉션 구현체를 반환하는게 최선일 수 있다
- 하지만 단지 컬렉션을 반환한다는 이유로 덩치 큰 시퀀스를 메모리에 올려서는 안된다
- 반환할 시퀀스의 크기가 크지만 표현을 간결하게 할 수 있다면 전용 컬렉션을 구현하는걸 고려하자
원소 시퀀스를 반환하는 메서드를 작성할 때는 이를 스트림으로 처리하기를 원하는 사용자와 반복으로 처리하길 원하는 사용자 모두를 고려하자
양쪽을다 만족 시킬수 있게 노력하며 컬렉션을 반환 가능하다면 컬렉션을 반환하자
반환 전부터 이미 원소들을 컬렉션에 담아 관리하거나 컬렉션을 하나 더 만들어도 될 정도로 원소 개수가 적다면 ArrayList 같은 표준 컬렉션을 사용하자
위와 반대의 경우에는 전용 컬렉션 구현을 고려하자
컬렉션을 반환하는게 불가능하면 Stream과 Iterable 중 더 자연스러운걸 반환하자
나중에 Stream 인터페이스가 Iterable을 지원하도록 자바가 수정되면 그때는 안심하고 스트림을 반환하면 된다
'책 > 이펙티브 자바' 카테고리의 다른 글
item 49 매개변수가 유효한지 검사하라 (0) 2022.04.13 item 48 스트림 병렬화는 주의해서 적용하라 (0) 2022.04.13 item 46 스트림에서는 부작용 없는 함수를 사용하라 (0) 2022.04.12 item 45 스트림은 주의해서 사용하라 (0) 2022.04.11 item 44 표준 함수형 인터페이스를 사용하라 (0) 2022.04.11