핵심 정리: 콜렉션 vs 스트림

콜렉션은 원소들을 효율적으로 관리하고, 조회하고, 수정하는데 집중.

스트림은 원소들에 직접 접근할 수 있는 방법을 제공하지 않는다.

interface Stream<T> extends BaseSteam<T, Steam<T>>, AutoCloseable

interface Collection<T> extends Iterable<T>

반복문에서만 쓰일거라면 Iterable.

스트림에서 쓰일거라면 Stream.

둘 모두를 고려한다면 Collection

// 스트림 <-> 반복자 어댑터 (285-286쪽)
public class Adapters {
    // 코드 47-3 Stream<E>를 Iterable<E>로 중개해주는 어댑터 (285쪽)
    public static <E> Iterable<E> iterableOf(Stream<E> stream) {
        return stream::iterator;
    }

    // 코드 47-4 Iterable<E>를 Stream<E>로 중개해주는 어댑터 (286쪽)
    **// 클라이언트 입장에서 추가적인 코드 작성이 필요하다는 단점** 
    public static <E> Stream<E> streamOf(Iterable<E> iterable) {
        return StreamSupport.stream(iterable.spliterator(), false);
    }

    public static void main(String[] args) {
        // Example list
        List<String> list = Arrays.asList("apple", "banana", "cherry");

        // Convert List to Stream
        Stream<String> stream = list.stream();

        // Convert Stream to Iterable using Adapters
        Iterable<String> iterable = Adapters.iterableOf(stream); // stream::iterator;
        
        System.out.println("Iterable from Stream:");
        for (String s : iterable) {
            System.out.println(s);
        }

        // Convert Iterable back to Stream using Adapters
        Stream<String> streamFromIterable = Adapters.streamOf(iterable);
        System.out.println("Stream from Iterable:");
        streamFromIterable.forEach(System.out::println);
    }
}