*알림 : *
Effective Java 3판은 Java 9까지 도입된 언어적 기능을 중심으로 서술되어 있습니다. 10버젼 이후의 Java 개발을 하시는 분들은 우회적인 접근법 대신 Java 언어 내 새로 도입된 기능이 더 간결하고 좋을 수 있습니다.해당 포스팅은 SSAFY 내 책읽기 스터디의 활동을 통해 작성된 포스팅입니다.
https://github.com/kjsu0209/JavaBook
https://medium.com/javabook
Stream 인터페이스는 Iterable 인터페이스의 추상 메서드를 모드 정의해 놓았지만, Iterable을 확장하지 않았다는 문제가 있다. forEach 구문을 사용하길 원한다면, 아래와 같은 정적 메서드를 이용할 수 있다.
예제 1 : Stream → Iterable adaptor
// Adapter from Stream<E> to Iterable<E>
public static <E> Iterable<E> iterableOf(Stream<E> stream) {
return stream::iterator;
}
for (ProcessHandle p : iterableOf(ProcessHandle.allProcesses())) {
// DO WHAT YOU WANT
}
반대로 Iterable을 Stream으로도 바꿀 수 있다.
예제 2 : Iterable → Stream adaptor
public static <E> Stream<E> streamOf(Iterable<E> iterable) {
return StreamSupport.stream(iterable.spliterator(), false);
}
위 두 가지 adaptor를 이용해 Stream/forEach 구문으로 처리하고자 하는 프로그래머 집단 모두를 만족할 수 있다. 그러나 adaptor는 코드를 지저분하게 하고, 성능상의 문제도 존재한다. (저자의 컴퓨터에서는 2.3배가 느려진다고 한다.) 그래서 하나의 리턴 타입만을 선택하는 것이 좋아보인다.
Collection VS Stream
Collection
- Collection 인터페이스는 Iterable의 하위타입이고 stream 메서드도 제공하니 일반적으론 Collection을 반환하는 편이 좋다.
- 하지만 Collection의 각 원소는 메모리에 올라가므로, 시퀀스의 크기가 크다면 고민해보는 것이 좋다.
- 반환할 시퀀스가 크더라도 표현을 간결하게 하여 전체 시퀀스를 메모리 위에 올리지 않고도 동작하도록 작성할 수 있다면 새 컬렉션을 구현하는 것을 생각해보자. PowerSet은, 각 원소의 인덱스를 비트 필드로 이용하는 아이디어다.
예제 3 : 전용 컬렉터 구현하기 : PowerSet을 반환하는 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) // size는 < 2^31-1인데, 30이 넘어가면 size()가 작동하지 않는다.
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;
}
};
}
}
Stream
- Collection 반환 예제와 같이 AbstractCollection을 활용하여 Collection을 리턴할 경우에는 contains와 size를 반환하여야 한다. 그러나 contains와 size를 시퀀스의 내용을 확정하기 전 까지 구할 수 없는 경우(i.e. 실제 반복을 돌려보기 전 까지는 무엇이 얼마나 들어갈지 예측이 불가능한 경우)에는 Stream을 반환하는 것이 좋다.
'IT > Effective Java' 카테고리의 다른 글
[Effective Java 3/E] ITEM 49. 매개변수가 유효한지 검사하라 (0) | 2021.04.14 |
---|---|
[Effective Java 3/E] ITEM 48. 스트림 병렬화는 주의해서 적용하라 (0) | 2021.04.14 |
[Effective Java 3/E] ITEM 46. 스트림에서는 부작용 없는 함수를 사용하라. (0) | 2021.04.14 |
[Effective Java 3/E] ITEM 45. 스트림은 주의해서 사용해라 (0) | 2021.04.14 |
[Effective Java 3/E] ITEM 44. 표준 함수형 인터페이스를 사용하라 (0) | 2021.04.14 |
댓글