πŸ“‚ JAVA/μ΄νŽ™ν‹°λΈŒ μžλ°”

λ°˜ν™˜ νƒ€μž…μœΌλ‘œλŠ” μŠ€νŠΈλ¦Όλ³΄λ‹€ μ»¬λ ‰μ…˜μ΄ λ‚«λ‹€ - [7μž₯. λžŒλ‹€μ™€ 슀트림(μ•„μ΄ν…œ47)]

Amenable 2023. 12. 9. 23:27

πŸ“™ 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'λ₯Ό μ°Έκ³ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.