반환타입으로 스트림보다 컬렉션이 나은 이유가 둘다 iterable을 구현하고 있지만 스트림은 iterable을 extend 하지 않아서 loop문이 정상적으로 동작 되지 않는다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
publicinterfaceBaseStream<T, S extendsBaseStream<T, S>> extendsAutoCloseable { /** * Returns an iterator for the elements of this stream. * * <p>This is a <a href="package-summary.html#StreamOps">terminal * operation</a>. * * @return the element iterator for this stream */ Iterator<T> iterator(); ..... }
/* * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.lang;
/** * Implementing this interface allows an object to be the target of the enhanced * {@code for} statement (sometimes called the "for-each loop" statement). * * @param <T> the type of elements returned by the iterator * * @since 1.5 * @jls 14.14.2 The enhanced {@code for} statement */ publicinterfaceIterable<T> { /** * Returns an iterator over elements of type {@code T}. * * @return an Iterator. */ Iterator<T> iterator();
/** * Performs the given action for each element of the {@code Iterable} * until all elements have been processed or the action throws an * exception. Actions are performed in the order of iteration, if that * order is specified. Exceptions thrown by the action are relayed to the * caller. * <p> * The behavior of this method is unspecified if the action performs * side-effects that modify the underlying source of elements, unless an * overriding class has specified a concurrent modification policy. * * @implSpec * <p>The default implementation behaves as if: * <pre>{@code * for (T t : this) * action.accept(t); * }</pre> * * @param action The action to be performed for each element * @throws NullPointerException if the specified action is null * @since 1.8 */ defaultvoidforEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
/** * Creates a {@link Spliterator} over the elements described by this * {@code Iterable}. * * @implSpec * The default implementation creates an * <em><a href="../util/Spliterator.html#binding">early-binding</a></em> * spliterator from the iterable's {@code Iterator}. The spliterator * inherits the <em>fail-fast</em> properties of the iterable's iterator. * * @implNote * The default implementation should usually be overridden. The * spliterator returned by the default implementation has poor splitting * capabilities, is unsized, and does not report any spliterator * characteristics. Implementing classes can nearly always provide a * better implementation. * * @return a {@code Spliterator} over the elements described by this * {@code Iterable}. * @since 1.8 */ default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }
그래서 스트림으로 반환하면 무조건 forEach문을 사용해야 된다 그래서 선택지를 스트림으로만 제한하기 때문이다.
publicabstractclassPowerSet { // 코드 47-5 입력 집합의 멱집합을 전용 컬렉션에 담아 반환한다. (287쪽) publicstaticfinal <E> Collection<Set<E>> of(Set<E> s) { List<E> src = newArrayList<>(s); if (src.size() > 30) thrownewIllegalArgumentException( "집합에 원소가 너무 많습니다(최대 30개).: " + s); returnnewAbstractList<Set<E>>() { @Override publicintsize() { // 멱집합의 크기는 2를 원래 집합의 원소 수만큼 거듭제곱 것과 같다. return1 << src.size(); }
@Override publicbooleancontains(Object o) { return o instanceof Set && src.containsAll((Set) o); }
@Override public Set<E> get(int index) { Set<E> result = newHashSet<>(); for (inti=0; index != 0; i++, index >>= 1) if ((index & 1) == 1) result.add(src.get(i)); return result; } }; }
// 리스트의 모든 부분리스트를 원소를 갖는 스트림을 생성하는 두 가지 방법 (288-289쪽) publicabstractclassSubLists { // 코드 47-6 입력 리스트의 모든 부분리스트를 스트림으로 반환한다. (288-289쪽) publicstatic <E> Stream<List<E>> of(List<E> list) { return Stream.concat(Stream.of(Collections.emptyList()), prefixes(list).flatMap(SubLists::suffixes)); }