HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
📖
공부한 책
/
📒
Effective Java
/
아이템 47: 반환 타입으로는 스트림보다 컬렉션이 낫다

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

💡
원소 시퀀스를 반환하는 메서드를 작성할 때는, 이를 스트림으로 처리하기를 원하는 사용자와 반복으로 처리하길 원하는 사용자가 모두 있을 수 있음을 떠올리고, 양쪽을 다 만족시키려 노력하자. (어답터 메서드를 제공함으로써) 컬렉션을 반환할 수 있다면 그렇게 하라. 반환 전부터 이미 원소들을 컬렉션에 담아 관리하고 있거나 컬렉션을 하나 더 만들어도 될 정도로 원소 개수가 적다면 ArrayList 같은 표준 컬렉션에 담아 반환하라 그렇지 않으면 앞서의 멱집합 예처럼 전용 컬렉션을 구현할지 고민하라. 컬렉션을 반환하는 게 불가능하면 스트림과 Iterable 중 더 자연스러운 것을 반환하라
원소 시퀀스 반환 가능한 종류가이드

원소 시퀀스 반환 가능한 종류

  • Collection 인터페이스
  • Iterable
  • 배열
  • Stream

가이드

  • 원소 시퀀스를 반환하는 공개 API의 반환 타입에는 Collection이나 그 하위 타입을 쓰는 게 일반적으로 최선
  • 하지만 단지 컬렉션을 반환한다는 이유로 덩치 큰 시퀀스를 메모리에 올려서는 안 된다.
    • 반환할 시퀀스가 크지만 표현을 간결하게 할 수 있다면 전용 컬렉션을 구현하는 방안을 검토 (AbstractList를 이용하여 전용 구현체를 만들기)
    • contains나 size를 구현하는게 불가능할 때(반복 시작되기 전에는 시퀀스의 내용을 확정할 수 없다는 등의 사유로)는 스트림이나 Iterable을 반환하는 편이 낫다. 원한다면 별도의 메서드를 두어 두 방식을 모두 제공해도 된다.
public class PowerSet { // Returns the power set of an input set as custom collection (Page 218) public static final <E> Collection<Set<E>> of(Set<E> s) { List<E> src = new ArrayList<>(s); if (src.size() > 30) throw new IllegalArgumentException("Set too big " + s); return new AbstractList<Set<E>>() { @Override public int size() { return 1 << src.size(); // 2 to the power srcSize } @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; } }; } public static void main(String[] args) { Set s = new HashSet(Arrays.asList(args)); System.out.println(PowerSet.of(s)); } }