Rantai Predikat Java 8

1. Ikhtisar

Dalam tutorial singkat ini, kita akan membahas berbagai cara untuk merangkai Predikat di Java 8.

2. Contoh Dasar

Pertama, mari kita lihat cara menggunakan Predikat sederhana untuk memfilter Daftar nama:

@Test public void whenFilterList_thenSuccess(){ List names = Arrays.asList("Adam", "Alexander", "John", "Tom"); List result = names.stream() .filter(name -> name.startsWith("A")) .collect(Collectors.toList()); assertEquals(2, result.size()); assertThat(result, contains("Adam","Alexander")); }

Dalam contoh ini, kami memfilter Daftar nama kami untuk hanya meninggalkan nama yang dimulai dengan "A" menggunakan Predikat :

name -> name.startsWith("A")

Tetapi bagaimana jika kita ingin menerapkan banyak Predikat ?

3. Beberapa Filter

Jika kita ingin menerapkan beberapa Predikat , salah satu opsinya adalah dengan menggabungkan beberapa filter:

@Test public void whenFilterListWithMultipleFilters_thenSuccess(){ List result = names.stream() .filter(name -> name.startsWith("A")) .filter(name -> name.length() < 5) .collect(Collectors.toList()); assertEquals(1, result.size()); assertThat(result, contains("Adam")); }

Sekarang kami telah memperbarui contoh kami untuk memfilter daftar kami dengan mengekstrak nama yang dimulai dengan "A" dan memiliki panjang kurang dari 5.

Kami menggunakan dua filter - satu untuk setiap Predikat .

4. Predikat Kompleks

Sekarang, daripada menggunakan beberapa filter, kita dapat menggunakan satu filter dengan Predikat yang kompleks :

@Test public void whenFilterListWithComplexPredicate_thenSuccess(){ List result = names.stream() .filter(name -> name.startsWith("A") && name.length() < 5) .collect(Collectors.toList()); assertEquals(1, result.size()); assertThat(result, contains("Adam")); }

Opsi ini lebih fleksibel daripada yang pertama, karena kita dapat menggunakan operasi bitwise untuk membuat Predikat serumit yang kita inginkan.

5. Menggabungkan Predikat

Selanjutnya, jika kita tidak ingin membuat Predikat yang kompleks menggunakan operasi bitwise, Java 8 Predicate memiliki metode berguna yang dapat kita gunakan untuk menggabungkan Predikat .

Kami akan menggabungkan Predikat menggunakan metode Predicate.and () , Predicate.or () , dan Predicate.negate ().

5.1. Predicate.and ()

Dalam contoh ini, kita akan mendefinisikan Predikat kita secara eksplisit, dan kemudian kita akan menggabungkannya menggunakan Predicate.and ():

@Test public void whenFilterListWithCombinedPredicatesUsingAnd_thenSuccess(){ Predicate predicate1 = str -> str.startsWith("A"); Predicate predicate2 = str -> str.length() < 5; List result = names.stream() .filter(predicate1.and(predicate2)) .collect(Collectors.toList()); assertEquals(1, result.size()); assertThat(result, contains("Adam")); }

Seperti yang bisa kita lihat, sintaksnya cukup intuitif, dan nama metode menyarankan jenis operasi. Menggunakan dan () , kami memfilter Daftar kami dengan mengekstrak hanya nama yang memenuhi kedua ketentuan tersebut.

5.2. Predicate.or ()

Kita juga bisa menggunakan Predicate.or () untuk menggabungkan Predicates.

Mari kita ekstrak nama yang dimulai dengan "J", serta nama dengan panjang kurang dari 4:

@Test public void whenFilterListWithCombinedPredicatesUsingOr_thenSuccess(){ Predicate predicate1 = str -> str.startsWith("J"); Predicate predicate2 = str -> str.length() < 4; List result = names.stream() .filter(predicate1.or(predicate2)) .collect(Collectors.toList()); assertEquals(2, result.size()); assertThat(result, contains("John","Tom")); }

5.3. Predicate.negate ()

Kita bisa menggunakan Predicate.negate () saat menggabungkan Predicates kita juga:

@Test public void whenFilterListWithCombinedPredicatesUsingOrAndNegate_thenSuccess(){ Predicate predicate1 = str -> str.startsWith("J"); Predicate predicate2 = str -> str.length() < 4; List result = names.stream() .filter(predicate1.or(predicate2.negate())) .collect(Collectors.toList()); assertEquals(3, result.size()); assertThat(result, contains("Adam","Alexander","John")); }

Di sini, kita telah menggunakan kombinasi atau () dan negate () untuk memfilter List menurut nama yang dimulai dengan "J" atau memiliki panjang tidak kurang dari 4.

5.4. Gabungkan Predikat Inline

Kita tidak perlu secara eksplisit mendefinisikan Predikat kita untuk digunakan dan (), atau () , dan negate ().

Kita juga bisa menggunakannya secara inline dengan menggunakan Predicate :

@Test public void whenFilterListWithCombinedPredicatesInline_thenSuccess(){ List result = names.stream() .filter(((Predicate)name -> name.startsWith("A")) .and(name -> name.length()<5)) .collect(Collectors.toList()); assertEquals(1, result.size()); assertThat(result, contains("Adam")); }

6. Menggabungkan Kumpulan Predikat

Akhirnya, mari kita lihat bagaimana merantai kumpulan Predikat dengan menguranginya.

Pada contoh berikut, kita memiliki Daftar dari Predikat yang kita digabungkan dengan menggunakan Predicate.and () :

@Test public void whenFilterListWithCollectionOfPredicatesUsingAnd_thenSuccess(){ List
    
      allPredicates = new ArrayList
     
      (); allPredicates.add(str -> str.startsWith("A")); allPredicates.add(str -> str.contains("d")); allPredicates.add(str -> str.length() > 4); List result = names.stream() .filter(allPredicates.stream().reduce(x->true, Predicate::and)) .collect(Collectors.toList()); assertEquals(1, result.size()); assertThat(result, contains("Alexander")); }
     
    

Perhatikan bahwa kami menggunakan identitas dasar kami sebagai:

x->true

Namun akan berbeda jika kita ingin menggabungkannya menggunakan Predicate.or () :

@Test public void whenFilterListWithCollectionOfPredicatesUsingOr_thenSuccess(){ List result = names.stream() .filter(allPredicates.stream().reduce(x->false, Predicate::or)) .collect(Collectors.toList()); assertEquals(2, result.size()); assertThat(result, contains("Adam","Alexander")); }

7. Kesimpulan

Dalam artikel ini, kami menjelajahi berbagai cara untuk merangkai Predikat di Java 8, dengan menggunakan filter (), membuat Predikat yang kompleks , dan menggabungkan Predikat.

Kode sumber lengkap tersedia di GitHub.