π 1. μμ μνμ€ λ°ν νμ λΉκ΅
μΌλ ¨μ μμ(μμ μνμ€)λ₯Ό λ°ννλ λ©μλλ μμμ΄ λ§λ€. μ΄λ° λ©μλμ λ°ν νμ μΌλ‘ Collection, Set, Listμ κ°μ μΈν°νμ΄μ€, Iterable, λ°°μ΄, μ€νΈλ¦Όμ΄ μ‘΄μ¬νλ€. μ΄ μ€ κ°μ₯ μ ν©ν νμ μ 컬λ μ μΈν°νμ΄μ€λ€.
λ§μ½, APIλ₯Ό μ€νΈλ¦Όλ§ λ°ννλλ‘ μ§λμΌλ©΄ λ°νλ μ€νΈλ¦Όμ for-eachλ‘ λ°λ³΅νκΈΈ μνλ μ¬μ©μλ λΉμ°ν λΆλ§μ ν λ‘ν κ²μ΄λ€. μ€νΈλ¦Όμ λ°λ³΅νκΈ° μν΄μλ μλμ κ°μ μ°ν λ°©λ²μ μ νν΄μΌ νλ€.
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())) {
...
}
λν, APIκ° Iterableλ§ λ°ννλ©΄ μ΄λ₯Ό μ€νΈλ¦Ό νμ΄νλΌμΈμμ μ²λ¦¬νλ €λ νλ‘κ·Έλλ¨Έκ° λΆλ§μ ν λ‘ν κ²μ΄λ€. μ΄λ¬ν κ²½μ°μλ μ΄λν°λ₯Ό μ΄μ©νμ¬ μ°ννλ λ°©λ²μ΄ μλ€.
public static <E> Stream<E> streamOf(Iterable<E> iterable) {
return StreamSupport.stream(iterable.spliterator(), false);
}
νμ§λ§, μΌλ°μ μΌλ‘λ κ³΅κ° APIλ₯Ό μμ±ν λλ μ€νΈλ¦Ό νμ΄νλΌμΈμ μ¬μ©νλ μ¬λκ³Ό λ°λ³΅λ¬Έμμ μ°λ €λ μ¬λ λͺ¨λλ₯Ό λ°°λ €ν΄μΌ νλ€. κ·Έλ κΈ° λλ¬Έμ μμ μνμ€μ λ°ννμ μΌλ‘λ Collection μΈν°νμ΄μ€κ° κ°μ₯ μ μ νλ€.
π 2. κΆμ₯μ¬ν 3κ°μ§
Collection μΈν°νμ΄μ€λ Iterableμ νμ νμ μ΄κ³ stream λ©μλλ μ 곡νλ λ°λ³΅κ³Ό μ€νΈλ¦Όμ λμμ μ§μνλ€. λ°λΌμ μμ μνμ€λ₯Ό λ°ννλ κ³΅κ° APIμ λ°ν νμ μλ Collectionμ΄λ κ·Έ νμ νμ μ μ°λ κ² μΌλ°μ μΌλ‘ μ΅μ μ΄λ€. μμ μνμ€λ₯Ό λ°ννλ κ²½μ° μλ 3κ°μ§ λ°©λ²μ μ°Έκ³ νλλ‘ νμ.
π 1. λ°ννλ μνμ€μ ν¬κΈ°κ° λ©λͺ¨λ¦¬μ μ¬λ €λ μμ ν λ§νΌ μλ€λ©΄ ArrayListλ HashSet κ°μ νμ€ μ»¬λ μ ꡬν체λ₯Ό λ°ννλ κ² μ΅μ μΌ μ μλ€.
π 2. λ°νν μνμ€κ° ν¬μ§λ§ ννμ κ°κ²°νκ² ν μ μλ€λ©΄ μ μ© μ»¬λ μ μ ꡬννλ λ°©μμ κ²ν ν΄ λ³΄μ.
λ©±μ§ν©(ν μ§ν©μ λͺ¨λ λΆλΆμ§ν©μ μμλ‘ νλ μ§ν©)μ μκ°ν΄ 보μ. μμ κ°μκ° nκ°λ©΄ λ©±μ§ν©μ μμ κ°μλ 2^nκ°κ° λλ€.
ν¬κΈ°κ° μ»€μ§ μ μκΈ° λλ¬Έμ μ΄λ₯Ό νμ€ μ»¬λ μ ꡬν체μ μ μ₯νλ €λ κ²μ μννλ€. κ·Έλ κΈ° λλ¬Έμ μλμ κ°μ΄ AbstractListλ₯Ό μ΄μ©νμ¬ μ μ© μ»¬λ μ μ ꡬνν μ μλ€.
public class PowerSet {
public static final <E> Collection<Set<E>> of(Set<E> s) {
List<E> src = new ArrayList<>();
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);
}
@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;
}
};
}
}
π 3. 컬λ μ μ λ°ννλ κ² λΆκ°λ₯νλ©΄ μ€νΈλ¦Όκ³Ό Iterable μ€ λ μμ°μ€λ¬μ΄ κ²μ λ°ννλΌ.
κ·Έλ¦¬κ³ λ°λ³΅μ μ¬μ©νλ κ² λ μμ°μ€λ¬μ΄ μν©μμλ μ¬μ©μλ κ·Έλ₯ μ€νΈλ¦Όμ μ°κ±°λ Streamμ Iterableλ‘ λ³νν΄ μ£Όλ μ΄λν°λ₯Ό μ¬μ©νλ κ² λ«λ€. (κ·Έλ¬λ μ΄λν°λ ν΄λΌμ΄μΈνΈ μ½λλ₯Ό μ΄μμ νκ² λ§λ€κ³ λ λλ¦¬κ² λ§λ λ€λ κ²μ μκ³ μμ΄μΌ νλ€.)
ν΄λΉ κΈμ Joshua Bloch λμ 'Effective Java 3/E'λ₯Ό μ°Έκ³ νμμ΅λλ€.