Saya melakukan penyelidikan di beberapa milis proyek lambda dan saya pikir saya menemukan beberapa diskusi yang menarik.
Sejauh ini saya belum menemukan penjelasan yang memuaskan. Setelah membaca semua ini, saya menyimpulkan bahwa itu hanyalah kelalaian. Tetapi Anda dapat melihat di sini bahwa itu telah dibahas beberapa kali selama bertahun-tahun selama desain API.
Lambda Libs Spec Ahli
Saya menemukan diskusi tentang ini di mailing list Lambda Libs Spec Experts :
Di bawah Iterable / Iterator.stream () Sam Pullara berkata:
Saya bekerja dengan Brian untuk melihat bagaimana fungsi limit / subtream [1] dapat diimplementasikan dan ia menyarankan konversi ke Iterator adalah cara yang tepat untuk melakukannya. Saya telah memikirkan solusi itu tetapi tidak menemukan cara yang jelas untuk mengambil iterator dan mengubahnya menjadi aliran. Ternyata itu ada di sana, Anda hanya perlu mengkonversi iterator menjadi spliterator dan kemudian mengubah spliterator menjadi stream. Jadi ini membawa saya untuk meninjau kembali apakah kita harus memiliki ini menggantung salah satu Iterable / Iterator secara langsung atau keduanya.
Saran saya adalah untuk setidaknya memilikinya di Iterator sehingga Anda dapat bergerak dengan bersih antara dua dunia dan itu juga akan mudah ditemukan daripada harus melakukan:
Streams.stream (Spliterators.spliteratorUnknownSize (iterator, Spliterator.ORDERED))
Dan kemudian Brian Goetz merespons :
Saya pikir maksud Sam adalah bahwa ada banyak kelas perpustakaan yang memberi Anda Iterator tetapi jangan biarkan Anda menulis spliterator Anda sendiri. Jadi yang bisa Anda lakukan adalah panggilan stream (spliteratorUnknownSize (iterator)). Sam menyarankan agar kami mendefinisikan Iterator.stream () untuk melakukannya untuk Anda.
Saya ingin menjaga metode stream () dan spliterator () sebagai penulis perpustakaan / pengguna tingkat lanjut.
Dan kemudian
"Mengingat bahwa menulis Spliterator lebih mudah daripada menulis Iterator, saya lebih suka menulis Spliterator daripada Iterator (Iterator sangat 90-an :)"
Kamu tidak mengerti intinya. Ada zillions kelas di luar sana yang sudah memberi Anda Iterator. Dan banyak dari mereka tidak siap spliterator.
Diskusi Sebelumnya di Mailing List Lambda
Ini mungkin bukan jawaban yang Anda cari tetapi dalam milis Project Lambda ini dibahas secara singkat. Mungkin ini membantu mendorong diskusi yang lebih luas tentang masalah ini.
Dalam kata-kata Brian Goetz di bawah Streams from Iterable :
Melangkah mundur ...
Ada banyak cara untuk membuat Stream. Semakin banyak informasi yang Anda miliki tentang cara mendeskripsikan elemen, semakin banyak fungsi dan kinerja yang dapat diberikan perpustakaan aliran. Dalam urutan paling tidak untuk sebagian besar informasi, mereka adalah:
Iterator
Iterator + ukuran
Spliterator
Spliterator yang tahu ukurannya
Spliterator yang mengetahui ukurannya, dan selanjutnya mengetahui bahwa semua sub-pemisahan mengetahui ukurannya.
(Beberapa orang mungkin terkejut menemukan bahwa kita dapat mengekstraksi paralelisme bahkan dari iterator yang bodoh dalam kasus-kasus di mana Q (pekerjaan per elemen) adalah non-trivial.)
Jika Iterable memiliki metode stream (), itu hanya akan membungkus Iterator dengan Spliterator, tanpa informasi ukuran. Tapi, kebanyakan hal-hal yang Iterable lakukan memiliki informasi ukuran. Yang berarti kami melayani aliran yang kurang. Itu tidak begitu baik.
Salah satu kelemahan dari praktik API yang digariskan oleh Stephen di sini, yaitu menerima Iterable dan bukannya Collection, adalah bahwa Anda memaksa hal-hal melalui "pipa kecil" dan karena itu membuang informasi ukuran ketika itu mungkin berguna. Tidak apa-apa jika semua yang Anda lakukan adalah untuk melakukannya, tetapi jika Anda ingin berbuat lebih banyak, lebih baik jika Anda dapat menyimpan semua informasi yang Anda inginkan.
Default yang disediakan oleh Iterable akan menjadi jelek - itu akan membuang ukuran meskipun sebagian besar Iterables tahu informasi itu.
Kontradiksi?
Meskipun, sepertinya diskusi didasarkan pada perubahan yang dilakukan Kelompok Pakar terhadap desain awal Streams yang awalnya didasarkan pada iterator.
Meski begitu, menarik untuk diperhatikan bahwa di antarmuka seperti Collection, metode stream didefinisikan sebagai:
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
Kode yang persis sama dengan yang digunakan dalam antarmuka Iterable.
Jadi, inilah mengapa saya mengatakan jawaban ini mungkin tidak memuaskan, tetapi masih menarik untuk dibahas.
Bukti Refactoring
Melanjutkan analisis di milis, sepertinya metode splitIterator pada awalnya berada di antarmuka Collection, dan pada beberapa titik di 2013 mereka memindahkannya ke Iterable.
Tarik splitIterator dari Koleksi ke Iterable .
Kesimpulan / Teori?
Maka kemungkinannya adalah bahwa kurangnya metode di Iterable hanya kelalaian, karena sepertinya mereka seharusnya telah memindahkan metode aliran juga ketika mereka memindahkan splitIterator dari Collection ke Iterable.
Jika ada alasan lain, itu tidak jelas. Ada yang punya teori lain?