Saya memiliki antarmuka yang mengembalikan java.lang.Iterable<T>
.
Saya ingin memanipulasi hasil itu menggunakan Java 8 Stream API.
Namun Iterable tidak dapat "streaming".
Adakah yang tahu cara menggunakan Iterable sebagai Stream tanpa mengubahnya menjadi Daftar?
java
java-8
java-stream
iterable
rayman
sumber
sumber
myIterable.stream()
tidak ada!Stream.of(iterable)
hasilkanStream<Iterable<Object>>
.Jawaban:
Ada jawaban yang jauh lebih baik daripada menggunakan
spliteratorUnknownSize
langsung, yang keduanya lebih mudah dan mendapatkan hasil yang lebih baik.Iterable
memilikispliterator()
metode, jadi Anda harus menggunakannya untuk mendapatkan spliterator Anda. Dalam kasus terburuk, ini adalah kode yang sama (menggunakan implementasi defaultspliteratorUnknownSize
), tetapi dalam kasus yang lebih umum, di mana AndaIterable
sudah menjadi koleksi, Anda akan mendapatkan spliterator yang lebih baik, dan karena itu kinerja streaming yang lebih baik (mungkin bahkan paralelisme yang baik). Itu juga lebih sedikit kode:Seperti yang Anda lihat, mendapatkan aliran dari
Iterable
(lihat juga pertanyaan ini ) tidak terlalu menyakitkan.sumber
Stream
akan menyenangkan, misalnyaStream.ofIterable(iterable)
.Jika Anda dapat menggunakan perpustakaan Guava, sejak versi 21, Anda dapat menggunakan
sumber
Lists.newArrayList(Iterable)
.Anda dapat dengan mudah membuat
Stream
dariIterable
atauIterator
:sumber
stream(...)
mengacaukan kode Anda?Saya ingin menyarankan menggunakan perpustakaan JOOL , ia menyembunyikan sihir spliterator di belakang panggilan Seq.seq (iterable) dan juga menyediakan sejumlah fungsionalitas tambahan yang bermanfaat.
sumber
Jadi sebagai jawaban lain yang disebutkan Guava memiliki dukungan untuk ini dengan menggunakan:
Saya ingin menyoroti bahwa implementasi melakukan sesuatu yang sedikit berbeda dari jawaban yang disarankan. Jika
Iterable
adalah tipeCollection
mereka melemparkannya.sumber
Saya telah membuat kelas ini:
Saya pikir itu sangat mudah dibaca karena Anda tidak perlu berpikir tentang spliterator dan boolean (isParallel).
sumber
Solusi yang sangat sederhana untuk masalah ini adalah membuat
Streamable<T>
antarmuka yang diperluasIterable<T>
yang menampungdefault <T> stream()
metode.Sekarang setiap dari Anda
Iterable<T>
s dapat trivial dibuat streamable hanya dengan menyatakan merekaimplements Streamable<T>
bukanIterable<T>
.sumber
Jika Anda menggunakan Vavr (sebelumnya dikenal sebagai Javaslang), ini bisa semudah:
sumber
Cara lain untuk melakukannya, dengan Java 8 dan tanpa lib eksternal:
sumber