을 반환하는 인터페이스가 java.lang.Iterable<T>
있습니다.
Java 8 Stream API를 사용하여 그 결과를 조작하고 싶습니다.
그러나 Iterable은 “스트리밍”할 수 없습니다.
Iterable을 List로 변환하지 않고 Stream으로 사용하는 방법에 대한 아이디어가 있습니까?
답변
spliteratorUnknownSize
직접 사용하는 것보다 훨씬 더 나은 대답이 있습니다. 더 쉽고 더 나은 결과를 얻을 수 있습니다. Iterable
이 spliterator()
당신이 당신 spliterator를 얻기 위해 그것을 사용한다, 그래서 방법을. 최악의 경우 동일한 코드 (기본 구현은 spliteratorUnknownSize
)를 사용 하지만 더 일반적인 경우에는 Iterable
이미 모음 인 경우 더 나은 스플리터를 얻을 수 있으므로 스트림 성능이 향상됩니다 (병렬 처리도 가능). 또한 코드가 적습니다.
StreamSupport.stream(iterable.spliterator(), false)
.filter(...)
.moreStreamOps(...);
보시다시피, 스트림에서 스트림을 얻는 것은 Iterable
( 이 질문 도 참조하십시오 ) 고통스럽지 않습니다.
답변
버전 21부터 Guava 라이브러리를 사용할 수있는 경우
Streams.stream(iterable)
답변
당신은 쉽게 만들 수 있습니다 Stream
중 Iterable
또는 Iterator
:
public static <T> Stream<T> stream(Iterable<T> iterable) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
iterable.iterator(),
Spliterator.ORDERED
),
false
);
}
답변
JOOL 라이브러리 사용을 제안 하고 싶습니다 .Seq.seq (iterable) 호출 뒤에 spliterator 마술을 숨기고 유용한 기능을 추가로 제공합니다.
답변
따라서 다른 답변으로 구아바는 다음을 사용하여이를 지원합니다.
Streams.stream(iterable);
구현이 제안 된 다른 답변과 약간 다른 점을 강조하고 싶습니다. (가) 경우 Iterable
유형 인 Collection
그들은 그것을 캐스팅.
public static <T> Stream<T> stream(Iterable<T> iterable) {
return (iterable instanceof Collection)
? ((Collection<T>) iterable).stream()
: StreamSupport.stream(iterable.spliterator(), false);
}
public static <T> Stream<T> stream(Iterator<T> iterator) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(iterator, 0),
false
);
}
답변
이 클래스를 만들었습니다.
public class Streams {
/**
* Converts Iterable to stream
*/
public static <T> Stream<T> streamOf(final Iterable<T> iterable) {
return toStream(iterable, false);
}
/**
* Converts Iterable to parallel stream
*/
public static <T> Stream<T> parallelStreamOf(final Iterable<T> iterable) {
return toStream(iterable, true);
}
private static <T> Stream<T> toStream(final Iterable<T> iterable, final boolean isParallel) {
return StreamSupport.stream(iterable.spliterator(), isParallel);
}
}
스플리터와 부울 (isParallel)에 대해 생각할 필요가 없기 때문에 완벽하게 읽을 수 있다고 생각합니다.
답변
이 문제에 대한 매우 간단한 해결 방법 은 메소드 를 보유하는 Streamable<T>
인터페이스 확장 을 작성 Iterable<T>
하는 default <T> stream()
것입니다.
interface Streamable<T> extends Iterable<T> {
default Stream<T> stream() {
return StreamSupport.stream(spliterator(), false);
}
}
이제 대신을 ( Iterable<T>
를) 선언하여 간단하게 스트리밍 할 수 있습니다 .implements Streamable<T>
Iterable<T>