Strim Java Null-Safe dari Koleksi

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan melihat cara membuat aliran selamat null dari koleksi Java.

Sebagai permulaan, beberapa keakraban dengan Java 8's Method References, Lambda Expressions, Optional dan Stream API diperlukan untuk memahami sepenuhnya bahan ini.

Sekiranya anda tidak mengetahui topik ini, lihat artikel kami sebelumnya: Ciri-ciri Baru di Java 8, Panduan Untuk Java 8 Pilihan dan Pengenalan Aliran Java 8.

2. Ketergantungan Maven

Sebelum kita memulakan, ada satu ketergantungan Maven yang kita perlukan untuk senario tertentu:

 org.apache.commons commons-collections4 4.2 

Yang biasa-collections4 perpustakaan boleh dimuat turun dari Maven Central.

3. Membuat Aliran dari Koleksi

Pendekatan asas untuk membuat Aliran dari mana-mana jenis Koleksi adalah memanggil kaedah aliran () atau parallelStream () pada koleksi bergantung pada jenis aliran yang diperlukan:

Collection collection = Arrays.asList("a", "b", "c"); Stream streamOfCollection = collection.stream(); 

Koleksi kami kemungkinan besar akan mempunyai sumber luaran pada satu ketika, kami mungkin akan menggunakan kaedah yang serupa dengan kaedah di bawah ini semasa membuat aliran dari koleksi:

public Stream collectionAsStream(Collection collection) { return collection.stream(); } 

Ini boleh menyebabkan beberapa masalah. Apabila koleksi yang disediakan menunjukkan rujukan nol , kod akan membuang NullPointerException pada waktu runtime.

Bahagian berikut membincangkan bagaimana kita dapat melindungi daripada perkara ini.

4. Menjadikan Aliran Koleksi yang Dibuat Tidak Selamat

4.1. Tambahkan Pemeriksaan untuk Mencegah Perbezaan Null

Untuk mengelakkan pengecualian penunjuk null yang tidak diingini , kita dapat memilih untuk menambahkan cek untuk mencegah rujukan nol ketika membuat aliran dari koleksi:

Stream collectionAsStream(Collection collection) { return collection == null ? Stream.empty() : collection.stream(); } 

Kaedah ini, bagaimanapun, mempunyai beberapa masalah.

Pertama, pemeriksaan sifar menghalangi logik perniagaan yang mengurangkan pembacaan keseluruhan program.

Kedua, penggunaan nol untuk mewakili ketiadaan nilai dianggap sebagai pendekatan yang salah pasca-Java SE 8: Ada cara yang lebih baik untuk memodelkan ketiadaan dan kehadiran nilai.

Penting untuk diingat bahawa Koleksi kosong tidak sama dengan Koleksi kosong . Walaupun yang pertama menunjukkan bahawa pertanyaan kami tidak mempunyai hasil atau elemen untuk ditunjukkan, yang kedua menunjukkan bahawa jenis ralat baru saja berlaku semasa proses.

4.2. Penggunaan emptyIfNull Menghubungi dari CollectionUtils Library

Kita boleh memilih untuk menggunakan Apache Commons CollectionUtils perpustakaan memastikan aliran kami adalah null selamat. Perpustakaan ini menyediakan emptyIfNull kaedah yang mengembalikan koleksi kosong tidak berubah-ubah diberi null koleksi sebagai hujah, atau koleksi itu sendiri sebaliknya:

public Stream collectionAsStream(Collection collection) { return emptyIfNull(collection).stream(); } 

Ini adalah strategi yang sangat mudah untuk diamalkan. Walau bagaimanapun, ia bergantung pada perpustakaan luaran. Jika dasar pembangunan perisian melarang penggunaan perpustakaan itu, maka penyelesaian ini diberikan null dan tidak sah.

4.3. Gunakan Pilihan Java 8

Java SE 8's Opsional adalah wadah bernilai tunggal yang mengandungi nilai atau tidak. Sekiranya tiada nilai, bekas Pilihan dikatakan kosong.

Menggunakan Pilihan boleh dibilang sebagai strategi keseluruhan terbaik untuk membuat koleksi selamat dari aliran.

Mari lihat bagaimana kita dapat menggunakannya diikuti dengan perbincangan ringkas di bawah:

public Stream collectionToStream(Collection collection) { return Optional.ofNullable(collection) .map(Collection::stream) .orElseGet(Stream::empty); } 
  • Optional.ofNullable (koleksi) membuatobjek Pilihan dari koleksi yang dilewatkan. Objek Pilihan kosongdibuat jika koleksi tidak ada.
  • peta (Koleksi :: aliran) mengekstrak nilai yang terdapat dalamobjek Pilihan sebagai argumen kepadakaedah peta ( Collection.stream () )
  • orElseGet (Stream :: blank) mengembalikan nilai fallback sekiranyaobjek Pilihan kosong, iaitu koleksi yang diluluskan adalah nol .

Hasilnya, kami secara proaktif melindungi kod kami daripada pengecualian penunjuk null yang tidak diingini .

4.4. Gunakan Stream OfNullable Java 9

Meneliti contoh ternary kami sebelumnya di bahagian 4.1. dan memandangkan kemungkinan beberapa elemen boleh menjadi kosong berbanding Koleksi , kami mempunyai kaedah Nullable di kelas Stream .

Kita boleh mengubah sampel di atas kepada:

Stream collectionAsStream(Collection collection) { return collection.stream().flatMap(s -> Stream.ofNullable(s)); }

5. Kesimpulan

Dalam artikel ini, kami meninjau secara ringkas cara membuat aliran dari koleksi tertentu. Kami kemudian terus meneroka tiga strategi utama untuk memastikan aliran yang dibuat tidak selamat semasa dibuat dari koleksi.

Akhirnya, kami menunjukkan kelemahan penggunaan setiap strategi jika relevan.

Seperti biasa, kod sumber lengkap yang menyertakan artikel boleh didapati di GitHub.