- 기본은 컬렉션이었고, 일부 Collection 메소드를 구현할 수 없을 때는 Iterable 인터페이스, 원소들이 기본타입, 성능에 민감하면 배열을 썼다.
- Java 8 부터 등장
- 스트림은 반복(iteration)을 지원하지 않는다.
- 따라서 스트림과 반복을 알맞게 조합해야 좋은 코드가 나온다.
// for-each 예시
for (String s : stringArrayList) {
System.out.println(s);
}
for(ProcessHandle ph : (Iterable<ProcessHandle>) ProcessHandle.allProcesses()::iterator) {
// ...프로세스
}
public static <E> Iterable<E> iterableOf(Stream<E> stream) {
return stream::iterator;
}
for(ProcessHandle p : iterableOf(ProcessHandle.allProcesses())){
//...프로세스
}
public static <E> Stream<E> streamOf(Iterable<E> iterable) {
return StreamSupport.stream(iterable.spliterator(), false);
}
- 멱집합 : 한 집합의 모든 부분집합, 원소가 n개면 멱집합의 원소 갯수는 2^n 개 이다.
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);
}
// 인덱스 n 번째 비트 값 : 해당 원소가 원래 집합의 n 번째 원소를 포함하는지 여부
@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;
}
};
}
}
- 각 원소의 인덱스를 비트 벡터로 사용했다.
- 시퀀스의 내용을 확정하지 못한다는 등의 사유로 두 메소드를 구현하는 것이 불가능하다면 스트림이나 Iterable을 리턴하는 편이 낫다.
public class SubLists {
public static <E> Stream<List<E>> of(List<E> list) {
return Stream.concat(Stream.of(Collections.emptyList()),
prefixes(list).flatMap(SubLists::suffixes));
}
private static <E> Stream<List<E>> prefixes(List<E> list) { // (a), (a,b), (a,b,c)
return IntStream.rangeClosed(1, list.size()) // 종료값 포함
.mapToObj(end -> list.subList(0, end));
}
private static <E> Stream<List<E>> suffixes(List<E> list) { // (a,b,c), (b,c), (c)
return IntStream.range(0, list.size()) //종료값 불포함
.mapToObj(start -> list.subList(start, list.size()));
}
}
- 참고 : 위 예시 메소드는 모든 부분 리스트를 반환하진 않는 듯하다. {a, c}가 나오지 않는다.
- 원소 개수가 적다면 표준 컬렉션을 이용하고, 작지 않다면 전용 컬렉션을 구현할 지 고민해보자.
- 스트림과 반복 모두에 사용될 수 있으니.
Reference: