Java 8에는 Stream <T> 클래스가 있는데 , 여기에는 흥미롭게 메소드가 있습니다
Iterator<T> iterator()
따라서 Iterable <T> 인터페이스를 구현할 것으로 예상 할 수 있는데,이 메소드는 정확히이 메소드를 필요로하지만 그렇지 않습니다.
foreach 루프를 사용하여 Stream을 반복하려면 다음과 같은 작업을 수행해야합니다
public static Iterable<T> getIterable(Stream<T> s) {
return new Iterable<T> {
@Override
public Iterator<T> iterator() {
return s.iterator();
}
};
}
for (T element : getIterable(s)) { ... }
여기에 뭔가 빠졌습니까?
답변
사람들은 이미 메일 링리스트 ☺ 에서 같은 것을 요청했습니다 . 주요 이유는 Iterable에도 반복 가능한 의미가 있지만 Stream은 그렇지 않습니다.
주된 이유는
Iterable
재사용 성 을 의미하는 반면,Stream
한 번만 사용할 수있는 것Iterator
입니다.경우
Stream
확장Iterable
후 기존의 코드가 놀랄 수 그것은받을 때Iterable
슬로우Exception
그들이 두 번째 시간for (element : iterable)
.
답변
개종하기 Stream
에를 Iterable
, 당신은 할 수있다
Stream<X> stream = null;
Iterable<X> iterable = stream::iterator
를 전달하는 Stream
방법에 기대하는 Iterable
,
void foo(Iterable<X> iterable)
간단히
foo(stream::iterator)
그러나 아마도 재미있을 것 같습니다. 좀 더 명확하게하는 것이 좋습니다.
foo( (Iterable<X>)stream::iterator );
답변
나는 StreamEx
구현 Iterable
(및 Stream
)뿐만 아니라에서 잃어버린 엄청나게 멋진 기능을 제공 한다고 지적하고 싶습니다 Stream
.
답변
for
다음과 같이 루프 에서 스트림을 사용할 수 있습니다 .
Stream<T> stream = ...;
for (T x : (Iterable<T>) stream::iterator) {
...
}
( 이 코드를 여기에서 실행 하십시오 )
(이것은 Java 8 기능 인터페이스 캐스트를 사용합니다.)
(이것은 위의 주석 중 일부 (예 : Aleksandr Dubinsky )에서 다루지 만 더 잘 보이게하기 위해 답변으로 가져 가고 싶었습니다.)
답변
kennytm 설명 그것은을 치료하는 데 안전하지 않은 이유 Stream
int로서 Iterable
, 그리고 종 유는 해결 방법이 제공 를 사용하여 허용 Stream
같이 Iterable
안전하지 않은 방식으로 불구을. 두 세계의 장점을 모두 얻을 수 있습니다. 사양 Iterable
에서 제공하는 Stream
모든 보증을 충족 하는 재사용이 가능 Iterable
합니다.
참고 : SomeType
여기서는 유형 매개 변수가 아닙니다. 적절한 유형 (예 :)으로 바꾸 String
거나 반사에 의존해야합니다.
Stream<SomeType> stream = ...;
Iterable<SomeType> iterable = stream.collect(toList()):
한 가지 큰 단점이 있습니다.
지연 반복의 이점은 사라집니다. 현재 스레드의 모든 값을 즉시 반복하려는 경우 오버 헤드는 무시할 수 있습니다. 그러나 부분적으로 또는 다른 스레드에서만 반복을 계획하는 경우이 즉각적이고 완전한 반복이 의도하지 않은 결과를 초래할 수 있습니다.
물론 가장 큰 장점은을 재사용 할 수 Iterable
있지만 (Iterable<SomeType>) stream::iterator
한 번만 사용할 수 있다는 것입니다. 수신 코드가 콜렉션에 대해 여러 번 반복되는 경우 이는 필수 일뿐만 아니라 성능에 유리할 수 있습니다.
답변
Stream
구현하지 않습니다 Iterable
. 일반적인 이해는 Iterable
반복해서 반복 될 수있는 모든 것입니다. Stream
재생할 수 없습니다.
내가 생각할 수있는 유일한 해결 방법은 스트림을 기반으로 반복 가능을 재생할 수있는 경우 스트림을 다시 만드는 것입니다. 내가 사용하고 Supplier
스트림의 새로운 인스턴스를 만들려면 아래, 매번 새로운 반복자가 생성됩니다.
Supplier<Stream<Integer>> streamSupplier = () -> Stream.of(10);
Iterable<Integer> iterable = () -> streamSupplier.get().iterator();
for(int i : iterable) {
System.out.println(i);
}
// Can iterate again
for(int i : iterable) {
System.out.println(i);
}
답변
타사 라이브러리를 사용하는 것이 마음에 들지 않으면 cyclops-react 는 Stream과 Iterable을 모두 구현하고 재생할 수있는 Stream을 정의합니다 ( kennytm 설명 문제 해결 ).
Stream<String> stream = ReactiveSeq.of("hello","world")
.map(s->"prefix-"+s);
또는 :-
Iterable<String> stream = ReactiveSeq.of("hello","world")
.map(s->"prefix-"+s);
stream.forEach(System.out::println);
stream.forEach(System.out::println);
[공개 나는 사이클롭스 반응의 주요 개발자입니다]