Saya ditanyai dalam sebuah wawancara dan saya tidak yakin saya memberikan jawaban terbaik yang bisa saya miliki. Saya menyebutkan bahwa Anda dapat melakukan pencarian paralel dan bahwa nilai nol ditangani oleh beberapa cara yang saya tidak ingat. Sekarang saya sadar saya sedang memikirkan Opsional. Apa yang kulewatkan di sini? Mereka mengklaim itu kode yang lebih baik atau lebih ringkas tetapi saya tidak yakin saya setuju.
Mempertimbangkan betapa ringkasnya jawaban itu, sepertinya ini bukanlah pertanyaan yang terlalu luas.
Jika mereka mengajukan pertanyaan ini di wawancara, dan jelas mereka, tujuan apa yang bisa memecahnya berfungsi selain untuk membuatnya lebih sulit untuk menemukan jawaban? Maksud saya, apa yang Anda cari? Saya dapat memecah pertanyaan dan memiliki semua sub-pertanyaan dijawab tetapi kemudian membuat pertanyaan orang tua dengan tautan ke semua pertanyaan ... sepertinya cukup konyol. Sementara kita sedang mengerjakannya, tolong beri saya contoh pertanyaan yang kurang luas. Saya tahu tidak ada cara untuk menanyakan hanya sebagian dari pertanyaan ini dan masih mendapatkan jawaban yang bermakna. Saya bisa mengajukan pertanyaan yang sama persis dengan cara yang berbeda. Misalnya, saya bisa bertanya, "Apa tujuan stream melayani?" atau "Kapan saya akan menggunakan aliran alih-alih untuk loop?" atau "Mengapa repot-repot dengan stream bukannya untuk loop?" Ini semua adalah pertanyaan yang persis sama.
... atau itu dianggap terlalu luas karena seseorang memberikan jawaban multi-point yang sangat panjang? Terus terang siapa pun yang tahu bisa melakukan itu dengan hampir semua pertanyaan. Misalnya, jika Anda adalah salah satu penulis JVM, Anda mungkin bisa membicarakan tentang loop sepanjang hari ketika kebanyakan dari kita tidak bisa.
"Harap edit pertanyaan untuk membatasi masalah khusus dengan detail yang cukup untuk mengidentifikasi jawaban yang memadai. Hindari mengajukan beberapa pertanyaan sekaligus. Lihat halaman Bagaimana Mengajukan Pertanyaan untuk membantu menjelaskan pertanyaan ini."
Seperti disebutkan di bawah ini, jawaban yang memadai telah diberikan yang membuktikan bahwa ada satu dan cukup mudah untuk diberikan.
sumber
Jawaban:
Menarik bahwa pertanyaan wawancara menanyakan tentang kelebihan, tanpa bertanya tentang kelemahan, karena keduanya ada.
Streaming adalah gaya yang lebih deklaratif . Atau gaya yang lebih ekspresif . Mungkin dianggap lebih baik untuk menyatakan maksud Anda dalam kode, daripada menjelaskan bagaimana hal itu dilakukan:
... mengatakan dengan sangat jelas bahwa Anda memfilter elemen yang cocok dari daftar, sedangkan:
Mengatakan "Saya sedang melakukan loop". Tujuan dari loop dikubur lebih dalam dalam logika.
Streaming sering terser . Contoh yang sama menunjukkan ini. Terser tidak selalu lebih baik, tetapi jika Anda bisa terse dan ekspresif pada saat yang sama, jauh lebih baik.
Streaming memiliki afinitas yang kuat dengan fungsi . Java 8 memperkenalkan lambdas dan antarmuka fungsional, yang membuka seluruh kotak mainan teknik yang kuat. Streaming menyediakan cara paling nyaman dan alami untuk menerapkan fungsi ke urutan objek.
Streaming mendorong lebih sedikit mutabilitas . Ini adalah semacam yang terkait dengan aspek pemrograman fungsional - jenis program yang Anda tulis menggunakan aliran cenderung jenis program di mana Anda tidak memodifikasi objek.
Streaming mendorong kopling yang lebih longgar . Kode penanganan aliran Anda tidak perlu tahu sumber arus, atau metode penghentian akhirnya.
Streaming dapat dengan singkat mengekspresikan perilaku yang cukup canggih . Sebagai contoh:
Sekilas mungkin terlihat seolah-olah itu menyaring seluruh aliran, lalu mengembalikan elemen pertama. Tetapi pada kenyataannya
findFirst()
mendorong seluruh operasi, sehingga efisien berhenti setelah menemukan satu item.Streaming menyediakan ruang untuk keuntungan efisiensi masa depan . Beberapa orang telah membuat tolok ukur dan menemukan bahwa aliran berulir tunggal dari in-memory
List
s atau array dapat lebih lambat daripada loop yang setara. Ini masuk akal karena ada lebih banyak objek dan overhead dalam permainan.Tapi skala aliran. Selain dukungan bawaan Java untuk operasi aliran paralel, ada beberapa perpustakaan untuk pengurangan peta terdistribusi menggunakan Streams sebagai API, karena modelnya sesuai.
Kerugian?
Kinerja :
for
Loop through array sangat ringan baik dalam hal heap maupun penggunaan CPU. Jika kecepatan mentah dan penghematan memori adalah prioritas, menggunakan aliran lebih buruk.Keakraban . Dunia ini penuh dengan programmer prosedural yang berpengalaman, dari banyak latar belakang bahasa, untuk siapa loop dikenal dan stream adalah novel. Di beberapa lingkungan, Anda ingin menulis kode yang biasa bagi orang semacam itu.
Overhead kognitif . Karena sifat deklaratifnya, dan peningkatan abstraksi dari apa yang terjadi di bawahnya, Anda mungkin perlu membangun model mental baru tentang bagaimana kode terkait dengan eksekusi. Sebenarnya Anda hanya perlu melakukan ini ketika ada kesalahan, atau jika Anda perlu menganalisis kinerja atau bug yang sangat halus. Ketika "hanya bekerja", itu hanya berfungsi.
Debugger membaik, tetapi bahkan sekarang, ketika Anda melangkah melalui kode aliran dalam debugger, itu bisa lebih sulit daripada loop setara, karena loop sederhana sangat dekat dengan variabel dan lokasi kode yang bekerja dengan debugger tradisional.
sumber
Disamping menyenangkan secara sintaksis, Streaming dirancang untuk bekerja dengan kumpulan data yang berpotensi besar tanpa batas, sedangkan array, Koleksi, dan hampir setiap kelas Java SE yang mengimplementasikan Iterable sepenuhnya ada dalam memori.
Kelemahan dari Stream adalah filter, pemetaan, dll., Tidak dapat membuang pengecualian yang diperiksa. Ini membuat Streaming pilihan yang buruk untuk, katakanlah, operasi I / O menengah.
sumber
Stream<Row>
- atau dimungkinkan untuk menulis sendiriStream
implementasi yang membungkus operasi kursor hasil DB.Arrays.asList("test", null).stream().forEach(s -> System.out.println(s.length()));
Anda salah sadari: operasi paralel menggunakan
Stream
s, bukanOptional
s.Anda bisa mendefinisikan metode yang bekerja dengan stream: menjadikannya sebagai parameter, mengembalikannya, dll. Anda tidak bisa menentukan metode yang menggunakan perulangan sebagai parameter. Ini memungkinkan operasi aliran yang rumit sekali dan menggunakannya berkali-kali. Perhatikan bahwa Java memiliki kelemahan di sini: metode Anda harus dipanggil
someMethod(stream)
sebagai berlawanan dengan aliran itu sendiristream.someMethod()
, jadi mencampurnya menyulitkan membaca: coba lihat urutan operasi diBanyak bahasa lain (C #, Kotlin, Scala, dll) memungkinkan beberapa bentuk "metode ekstensi".
Bahkan ketika Anda hanya membutuhkan operasi berurutan, dan tidak ingin menggunakannya kembali, sehingga Anda bisa menggunakan stream atau loop, operasi sederhana pada stream mungkin berhubungan dengan perubahan yang cukup rumit dalam loop.
sumber
Optional
adalah alternatif untuknull
, tetapi tidak ada hubungannya dengan operasi paralel. Kecuali "Sekarang saya sadar saya sedang memikirkan Opsional" dalam pertanyaan Anda hanya berbicara tentangnull
penanganan?Anda mengulang urutan (array, koleksi, masukan, ...) karena Anda ingin menerapkan beberapa fungsi ke elemen urutan.
Streaming memberi Anda kemampuan untuk menyusun fungsi pada elemen urutan dan memungkinkan untuk mengimplementasikan fungsi yang paling umum (misalnya memetakan, memfilter, menemukan, menyortir, mengumpulkan, ...) terlepas dari case konkret.
Oleh karena itu diberikan beberapa tugas pengulangan dalam banyak kasus Anda dapat mengekspresikannya dengan kode lebih sedikit menggunakan Streaming, yaitu Anda mendapatkan keterbacaan .
sumber
Saya akan mengatakan paralelisasi yang sangat mudah digunakan. Coba iterasi jutaan entri secara paralel dengan for for loop. Kami pergi ke banyak CPU, tidak lebih cepat; jadi semakin mudah untuk berjalan secara paralel semakin baik, dan dengan
Stream
s ini sangat mudah.Yang paling saya sukai adalah verbositas yang mereka tawarkan. Butuh sedikit waktu untuk memahami apa yang sebenarnya mereka lakukan dan hasilkan sebagai lawan dari bagaimana mereka melakukannya.
sumber