Java Stream Filter dengan Lambda Expression

1. Perkenalan

Dalam tutorial singkat ini, kita akan menjelajahi penggunaan metode Stream.filter () saat kita bekerja dengan Streams di Java.

Kami akan melihat cara menggunakannya, dan cara menangani kasus khusus dengan pengecualian yang dicentang.

2. Menggunakan Stream.filter ()

Metode filter () adalah operasi perantara dari antarmuka Stream yang memungkinkan kita untuk memfilter elemen aliran yang cocok dengan Predikat yang diberikan :

Stream filter(Predicate predicate)

Untuk melihat cara kerjanya, mari buat kelas Pelanggan :

public class Customer { private String name; private int points; //Constructor and standard getters }

Selain itu, mari buat kumpulan pelanggan:

Customer john = new Customer("John P.", 15); Customer sarah = new Customer("Sarah M.", 200); Customer charles = new Customer("Charles B.", 150); Customer mary = new Customer("Mary T.", 1); List customers = Arrays.asList(john, sarah, charles, mary);

2.1. Memfilter Koleksi

Kasus penggunaan umum metode filter () adalah memproses koleksi.

Mari buat daftar pelanggan dengan lebih dari 100 poin. Untuk melakukan itu, kita dapat menggunakan ekspresi lambda:

List customersWithMoreThan100Points = customers .stream() .filter(c -> c.getPoints() > 100) .collect(Collectors.toList());

Kita juga bisa menggunakan referensi metode, yang merupakan singkatan dari ekspresi lambda:

List customersWithMoreThan100Points = customers .stream() .filter(Customer::hasOverHundredPoints) .collect(Collectors.toList());

Dalam kasus ini, kami menambahkan metode hasOverHundredPoints ke kelas Pelanggan kami :

public boolean hasOverHundredPoints() { return this.points > 100; }

Dalam kedua kasus tersebut, kami mendapatkan hasil yang sama:

assertThat(customersWithMoreThan100Points).hasSize(2); assertThat(customersWithMoreThan100Points).contains(sarah, charles);

2.2. Memfilter Koleksi dengan Beberapa Kriteria

Selanjutnya, kita dapat menggunakan beberapa kondisi dengan filter () . Misalnya, kita dapat memfilter berdasarkan poin dan nama :

List charlesWithMoreThan100Points = customers .stream() .filter(c -> c.getPoints() > 100 && c.getName().startsWith("Charles")) .collect(Collectors.toList()); assertThat(charlesWithMoreThan100Points).hasSize(1); assertThat(charlesWithMoreThan100Points).contains(charles);

3. Penanganan Pengecualian

Sampai saat ini, kami telah menggunakan filter dengan predikat yang tidak mengeluarkan pengecualian. Memang, antarmuka fungsional di Java tidak mendeklarasikan pengecualian yang dicentang atau tidak dicentang .

Selanjutnya kita akan menunjukkan beberapa cara berbeda untuk menangani pengecualian dalam ekspresi lambda.

3.1. Menggunakan Custom Wrapper

Pertama, kami akan mulai dengan menambahkan profilePhotoUrl ke Pelanggan kami :

private String profilePhotoUrl;

Selain itu, mari tambahkan metode hasValidProfilePhoto () sederhana untuk memeriksa ketersediaan profil:

public boolean hasValidProfilePhoto() throws IOException { URL url = new URL(this.profilePhotoUrl); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); return connection.getResponseCode() == HttpURLConnection.HTTP_OK; }

Kita bisa melihat bahwa metode hasValidProfilePhoto () melontarkan IOException . Sekarang jika kita mencoba memfilter pelanggan dengan metode ini:

List customersWithValidProfilePhoto = customers .stream() .filter(Customer::hasValidProfilePhoto) .collect(Collectors.toList());

Kami akan melihat kesalahan berikut:

Incompatible thrown types java.io.IOException in functional expression

Untuk mengatasinya, salah satu alternatif yang bisa kita gunakan adalah membungkusnya dengan blok coba-tangkap:

List customersWithValidProfilePhoto = customers .stream() .filter(c -> { try { return c.hasValidProfilePhoto(); } catch (IOException e) { //handle exception } return false; }) .collect(Collectors.toList());

Jika kita perlu membuang pengecualian dari predikat kita, kita bisa membungkusnya dalam pengecualian yang tidak dicentang seperti RuntimeException .

3.2. Menggunakan ThrowingFunction

Alternatifnya, kita bisa menggunakan pustaka ThrowingFunction.

ThrowingFunction adalah pustaka sumber terbuka yang memungkinkan kita menangani pengecualian yang dicentang di antarmuka fungsional Java.

Mari kita mulai dengan menambahkan dependensi fungsi-lempar ke pom kita:

 pl.touk throwing-function 1.3 

Untuk menangani pengecualian dalam predikat, pustaka ini menawarkan kepada kita kelas ThrowingPredicate , yang memiliki metode unchecked () untuk membungkus pengecualian yang dicentang.

Mari kita lihat aksinya:

List customersWithValidProfilePhoto = customers .stream() .filter(ThrowingPredicate.unchecked(Customer::hasValidProfilePhoto)) .collect(Collectors.toList());

4. Kesimpulan

Dalam artikel ini, kami melihat contoh cara menggunakan metode filter () untuk memproses aliran. Kami juga mempelajari beberapa alternatif untuk menangani pengecualian.

Seperti biasa, kode lengkap tersedia di GitHub.