47. 반환 타입으로는 스트림보다 컬렉션이 낫다.

무한성장개발자·2025년 9월 25일

package me.whiteship.chapter07.item47;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

// 스트림 <-> 반복자 어댑터 (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);
        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);
    }
}
package me.whiteship.chapter07.item47;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

// 스트림 <-> 반복자 어댑터 (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);
        Iterable<String> iterable = () -> 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);
    }
}

이렇게는 되지만

package me.whiteship.chapter07.item47;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

// 스트림 <-> 반복자 어댑터 (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);
//        Iterable<String> iterable = () -> stream.iterator();
        System.out.println("Iterable from Stream:");
        for (String s : () -> stream.iterator()) {
            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);
    }
}

이렇게는 안되고

package me.whiteship.chapter07.item47;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

// 스트림 <-> 반복자 어댑터 (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);
//        Iterable<String> iterable = () -> stream.iterator();
        System.out.println("Iterable from Stream:");
        for (String s : (Iterable<String>)() -> stream.iterator()) {
            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);
    }
}

이렇게 붙여주면 된다.

결국에 저 함수가 맨 위에 잇는 함수와 동일하다.

package me.whiteship.chapter07.item47;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

// 리스트의 모든 부분리스트를 원소를 갖는 스트림을 생성하는 두 가지 방법 (288-289쪽)
public class SubLists {
    // 코드 47-6 입력 리스트의 모든 부분리스트를 스트림으로 반환한다. (288-289쪽)
    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) {
        return IntStream.rangeClosed(1, list.size())
                .mapToObj(end -> list.subList(0, end));
    }

    private static <E> Stream<List<E>> suffixes(List<E> list) {
        return IntStream.range(0, list.size())
                .mapToObj(start -> list.subList(start, list.size()));
    }

//    // 코드 47-7 입력 리스트의 모든 부분리스트를 스트림으로 반환한다(빈 리스트는 제외). (289쪽)
//    // 289쪽의 명확한 반복 코드의 변형이다.
//    public static <E> Stream<List<E>> of(List<E> list) {
//        return IntStream.range(0, list.size())
//                .mapToObj(start ->
//                        IntStream.rangeClosed(start + 1, list.size())
//                                .mapToObj(end -> list.subList(start, end)))
//                .flatMap(x -> x);
//    }

    public static void main(String[] args) {
        List<String> list = Arrays.asList(args);
        SubLists.of(list).forEach(System.out::println);
    }
}
package me.whiteship.chapter07.item47;

import java.util.*;

public class PowerSet {
    // 코드 47-5 입력 집합의 멱집합을 전용 컬렉션에 담아 반환한다. (287쪽)
    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);
            }

            @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;
            }
        };
    }

    public static void main(String[] args) {
        Set s = new HashSet(Arrays.asList(args));
        System.out.println(PowerSet.of(s));
    }
}

위 2개는 알아서 보기.

0개의 댓글