CodeGym /จาวาบล็อก /สุ่ม /Java เพรดิเคตพร้อมตัวอย่าง
John Squirrels
ระดับ
San Francisco

Java เพรดิเคตพร้อมตัวอย่าง

เผยแพร่ในกลุ่ม
โดยทั่วไปภาคแสดงหมายถึงคำสั่งที่กำหนดว่าค่าอาจเป็นจริงหรือเท็จ ในการเขียนโปรแกรมเพรดิเคต หมายถึง ฟังก์ชันที่มีหนึ่งอาร์กิวเมนต์ที่ส่งคืนค่าบูลีน Functional Interface Predicate ถูกนำมาใช้ใน Java 8 "Functional" หมายความว่ามีวิธีการนามธรรมเพียงวิธีเดียว ยอมรับอาร์กิวเมนต์และส่งกลับค่าบูลีน ใน Java อินเทอร์เฟซการทำงานจะใช้สำหรับจัดการนิพจน์ Lambda ตัวสร้าง และการอ้างอิงเมธอด โดยปกติแล้ว Java 8 Predicate จะใช้เพื่อใช้ตัวกรองสำหรับคอลเลกชันของวัตถุ มาดูการใช้งานหลักและวิธีการที่ใช้กันอย่างแพร่หลาย รวมถึงการแก้ปัญหาในการฝึกปฏิบัติ เพรดิเคต Java พร้อมตัวอย่าง - 1

เหตุใดนักพัฒนาจึงใช้เพรดิเคต

โดยทั่วไป นักพัฒนาสามารถใช้เพรดิเคตสำหรับงานใดๆ ที่เกี่ยวข้องกับการประเมินรายการตามเกณฑ์ที่กำหนดไว้ล่วงหน้าและส่งกลับค่าบูลีน ต่อไปนี้คือตัวอย่างงานง่ายๆ ที่นักพัฒนาจัดการโดยใช้เพรดิเคต:
  • การกรองชุดของจำนวนเต็ม
  • การจัดเรียงรายการโดยตรวจสอบให้แน่ใจว่าข้อมูลเป็นไปตามเงื่อนไขที่กำหนดไว้ล่วงหน้าหลายประการ (เช่น จัดระเบียบรายการต่างๆ โดยกำหนดเงื่อนไขราคาและน้ำหนัก)
  • การใช้ยูทิลิตี้แพ็คเกจในการเขียนโปรแกรมพร้อมกัน
เพรดิเคตเป็นคุณสมบัติที่สำคัญในการทดสอบซอฟต์แวร์ อินเทอร์เฟซการทำงานช่วยให้แยกหน่วยสำหรับการทดสอบได้ง่ายขึ้น ปรับปรุงความสามารถในการอ่านและความสามารถในการจัดการโค้ดแอป

ไวยากรณ์เพรดิเคตในภาษาจาวา

java.util.function.Predicateถูกนำมาใช้ใน Java 8 เพื่อเป็นทางเลือกในการจัดการการแสดงผลการประเมินใน Lambda มุมมองมาตรฐานของอินเทอร์เฟซคือPredicate<T>โดยที่ T เป็นอาร์กิวเมนต์เดียวที่ส่งคืนค่าบูลีน Java Predicates มีการทดสอบวิธีการทำงาน (นามธรรม) (Object)ที่ประเมินเพรดิเคตนี้บน Object ที่กำหนด

@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
ต่อไปนี้คือตัวอย่างการเขียนเพรดิเคตง่ายๆ ที่กรองจำนวนเต็มตามเงื่อนไข "มากกว่า", "น้อยกว่า"

// An example of a simple Java predicate
  
import java.util.function.Predicate; 
public class PredicateExample { 
    public static void main(String[] args) 
    { 
        // Creating predicate 
        Predicate<Integer> lesserThan = i -> (i < 18);  
  
        // Calling Predicate method 
        System.out.println(lesserThan.test(10));  
    }
}
ผลลัพธ์จะเป็นจริงเพราะ 10 < 18 อีกหนึ่งตัวอย่างที่มีเพรดิเคตในfilter( ) เพรดิเคตช่วยกรองผู้ใหญ่ทั้งหมดจากรายการอายุ

  import java.util.List;
  import java.util.function.Predicate;

  public class PredicateExample {
      public static void main(String[] args) {
          List<Integer> ages = List.of(17, 18, 19, 28, 18, 28, 46, 7, 8, 9, 21, 12);
          NotLessThan18<Integer> isAdult = new NotLessThan18<>();
          ages.stream().filter(isAdult).forEach(System.out::println);
      }
  }



class NotLessThan18<E> implements Predicate<Integer> {

      @Override
      public boolean test(Integer v) {
          Integer ADULT = 18;
          return v >= ADULT;
      }
  }
ผลลัพธ์คือ:
18 19 28 18 28 46 21

วิธีเพรดิเคต Java 8

Predicate Interface มีหลายวิธี
  • การทดสอบบูลีน (T t)ประเมินภาคแสดงของอาร์กิวเมนต์ที่กำหนด
  • เพรดิเคตเริ่มต้น<T> และ (เพรดิเคต<? super T> อื่น ๆ)ส่งคืนเพรดิเคตที่แสดงถึงตรรกะการลัดวงจร AND ของเพรดิเคตนี้และเพรดิเคตอื่น
  • เพรดิเคตเริ่มต้น<T> หรือส่งคืนเพรดิเคตที่ประกอบขึ้นซึ่งแสดงถึงตรรกะ OR ที่ลัดวงจรของเพรดิเคตนี้และเพรดิเคตอื่น
  • เพรดิเคตเริ่มต้น<T> ลบล้าง()ส่งคืนเพรดิเคตที่อยู่ตรงข้ามกับเพรดิเคตนี้อย่างมีเหตุผล
  • เริ่มต้น Predicate<T> isEqual(Object targetRef)ส่งคืนผลลัพธ์ของการทดสอบหากสองอาร์กิวเมนต์เท่ากันตามObjects.equals(Object, Object )

การทดสอบบูลีน(T t)

นี่เป็นวิธีการทำงานสำหรับเพรดิเคต Java ที่ประเมินว่าอาร์กิวเมนต์ที่กำหนดตรงตามเงื่อนไขของเพรดิเคตหรือไม่ ตัวอย่าง: ที่นี่เราสร้างเพรดิเคตผู้ใหญ่สำหรับทุกคนที่มีอายุ 18 ปีขึ้นไป วิธี การทดสอบ ()รับค่าจำนวนเต็มและตรวจสอบ

import java.util.function.Predicate;
public class PredicateTestTest {
   public static void main(String[] args) {
       Predicate<Integer> adult = i -> i >= 18;
       System.out.println(adult.test(12));
       System.out.println(adult.test(19));
       System.out.println(adult.test(21));
   }
}
ผลลัพธ์ของโค้ดด้านบนจะเป็นอย่างไร ในกรณีแรก เนื่องจาก 12 น้อยกว่า 18 จะเป็นเท็จ สำหรับสถานการณ์สมมติที่สองและสาม เป็นไปตามเงื่อนไข ดังนั้นผลตอบแทนจะเป็นจริง
เท็จ จริง จริง

เพรดิเคตเริ่มต้นและ ()

วิธีนี้แสดงถึงตัวดำเนินการ "และ" นั่นเป็นเหตุผลว่าทำไม ถ้าหนึ่งในภาคแสดงที่กำหนดไม่เป็นไปตามเงื่อนไขที่ตั้งไว้ อีกภาคหนึ่งจะไม่ได้รับการประเมิน ตัวอย่าง: ลองเขียนเพรดิเคตใน Java โดยกรองทุกคนที่เป็นผู้ใหญ่แล้วแต่อายุน้อยกว่า 65 ปีโดยใช้and () มาใช้เพรดิเคต.เพิ่ม ()และเขียนเพรดิเคต java ด้วยแลมบ์ดาสำหรับเงื่อนไขเหล่านี้: หากเงื่อนไขเป็นจริง แอปจะส่งกลับข้อความต่อไปนี้:

import java.util.function.Predicate;

   public class PredicateDemo {
       public static void main(String[] args) {
           Predicate<Integer> adultYet = i -> i >= 18;
           Predicate<Integer> adultStill = i -> i < 65;
           System.out.println(adultYet.and(adultStill).test(5));
           System.out.println(adultYet.and(adultStill).test(38));
           System.out.println(adultYet.and(adultStill).test(90));
       }
   }
ผลลัพธ์คือ:
เท็จ จริง เท็จ

เพรดิเคตเริ่มต้นหรือ ()

Predicate.or()วิธีการแทนตัวดำเนินการ "OR" ซึ่งหมายความว่าเงื่อนไขจะยังคงเป็นจริงแม้ว่าเพรดิเคตหนึ่งในสองเพรดิเคตจะเป็นจริงและอีกเพรดิเคตเป็นเท็จ ตัวอย่าง: เรามาประเมินสตริงอักขระกัน ลองใช้เมธอด OR เพื่อจัดเรียงวลีทั้งหมดที่มีสตริงย่อย “my” หรือ “crayon”

import java.util.function.Predicate;

  public class PredicateDemo2 {
      public static void main(String[] args) {
          Predicate<String> containsA = t -> t.contains("crayon");
          Predicate<String> containsB = t -> t.contains("my");
          System.out.println(containsA.or(containsB).test("here is my crayon"));
          System.out.println(containsA.or(containsB).test("here is my pencil"));
          System.out.println(containsA.or(containsB).test("here is John's crayon"));
          System.out.println(containsA.or(containsB).test("here is John's pencil"));
      }
  }
ผลลัพธ์คือ:
จริง จริง จริง เท็จ

เพรดิเคตปฏิเสธ () เริ่มต้น

เมธอด negate()ใช้เพื่อรวบรวมค่าทั้งหมดที่ไม่เป็นไปตามเกณฑ์ที่กำหนดไว้ล่วงหน้า ตัวอย่าง: ถ้าคุณต้องการจัดเรียงตามคลาส “Tomatoes” และค้นหารายการทั้งหมดที่ไม่ใช่ “สีแดง” คุณสามารถเขียนภาคแสดงและสแกนลำดับทั้งหมดได้อย่างรวดเร็ว ลองเขียนโค้ดสำหรับโค้ดนี้ด้วยตัวคุณเองและตรวจสอบกับโซลูชันเมื่อทำเสร็จแล้ว

import java.util.function.Predicate;

public class PredicateDemo3 {
public static void main(String[] args) {
 Predicate<Integer> adult = i -> i >= 18;
System.out.println(adult.negate().test(7));  System.out.println(adult.negate().test(19))
  }
   }
ผลลัพธ์คือ:
ถูกผิด

เพรดิเคตคงที่เท่ากับ (Object targetRef)

วิธีนี้มีประโยชน์อย่างมากหากคุณต้องการตรวจสอบว่าอ็อบเจกต์สองตัวเท่ากับค่าที่กำหนดเป็นพารามิเตอร์ของ Objects.equals() หรือไม่ วิธีนี้มีประโยชน์อย่างยิ่งหากคุณต้องการเปรียบเทียบผลการทดสอบที่คล้ายกัน ตัวอย่าง: สมมติว่าคุณกำลังเปรียบเทียบลูกแพร์สองตู้และต้องการตรวจสอบว่าผลไม้ทั้งสองลูกมีน้ำหนักและสีมาตรฐานหรือไม่ ในกรณีนี้ static Predicate isEqual(Object targetRef)คือเมธอดที่คุณต้องการ มาดูกันว่าisEqualตรวจสอบความเท่าเทียมกันของสองสตริงอย่างไร:

import java.util.function.Predicate;

public class PredicateDemo2 {
   public static void main(String[] args) {
       Predicate<String> i = Predicate.isEqual("here is my crayon");
       System.out.println(i.test("here is my pencil"));
       System.out.println(i.test("here is my crayon"));
   }
}
หากวัตถุที่คุณกำลังวิเคราะห์เป็นไปตามเงื่อนไขมาตรฐาน ฟังก์ชันจะคืนค่าเป็นจริง ผลลัพธ์คือ:
ผิดถูก

Java IntPredicate

Java IntPredicate เป็นอินเทอร์เฟซการทำงาน ดังนั้นคุณสามารถใช้เป็นเป้าหมายการกำหนดสำหรับนิพจน์แลมบ์ดาหรือการอ้างอิงเมธอด IntPredicate ทำงานบนจำนวนเต็มและส่งกลับค่าเพรดิเคตตามเงื่อนไข เช่น Predicate Interface, IntPredicate ยังมีเมธอด test()และ() , negate()หรือ( ) นี่คือตัวอย่างของ IntPredicate นอกจากนี้ยังกรองผู้ใหญ่ทั้งหมด (18 คนขึ้นไป) จากอาร์เรย์

import java.util.Arrays;
import java.util.function.IntPredicate;

public class IntPredicateExample {

   public static void main(String[] args) {

       int[] ages = { 18, 28, 18, 46, 90, 45, 2, 3, 1, 5, 7, 21, 12 };

       IntPredicate p = n -> n >= 18;

       Arrays.stream(ages).filter(p).forEach(System.out::println);
   }
}
ผลลัพธ์คือ:
18 28 18 46 90 45 21

การเขียน Clean Predicates ใน Java

Java Predicates ใช้งานได้ดีและสนุกในการทำงาน อย่างไรก็ตาม หากคุณไม่ใส่ใจว่าการแสดงออกของแลมบ์ดาที่คุณเขียนส่งผลกระทบต่อโค้ดอย่างไร ก็มีความเสี่ยงที่จะลดความสามารถในการบำรุงรักษาโค้ดด้วยเพรดิเคตที่ยุ่งเหยิง แนวทางปฏิบัติง่ายๆ ต่อไปนี้จะช่วยให้คุณมั่นใจได้ว่าอินเทอร์เฟซการทำงานของคุณนั้นจัดการและอ่านได้ง่าย
  • Don't Repeat Yourself — อย่าเขียนเพรดิเคตด้วย Java ที่มีค่า เมธอด และเงื่อนไขซ้ำๆ กันมากกว่าหนึ่งครั้ง ด้วยวิธีนี้ คุณจะเสียเวลาในการผลิตและทำให้โค้ดยุ่งเหยิง
  • แยกเพรดิเคตออกจากโค้ดแอปเพื่อให้แน่ใจว่าสามารถทดสอบได้ นอกเหนือจากนั้น ให้สร้างตารางการทดสอบหน่วยเพรดิเคตและทำตามนั้น
  • ใช้การนำเข้าและรูปแบบการจัดองค์ประกอบเพื่อให้แน่ใจว่าชั้นเรียนของคุณจะไม่บวมและจัดการได้ง่าย
  • พิจารณาย้ายเพรดิเคต Java ไปที่คลาส Helper — ด้วยวิธีนี้ คุณจะปรับปรุงการนำโค้ดของคุณกลับมาใช้ใหม่ได้และอำนวยความสะดวกในการบำรุงรักษา
  • อ่านง่าย — เมื่อใดก็ตามที่เป็นไปได้ ให้เลือกคำสั่งแบบบรรทัดเดียวมากกว่าภาคแสดงที่ซับซ้อน การแสดงความเข้าใจของคุณเกี่ยวกับอินเทอร์เฟซการทำงานที่ซับซ้อนอาจเป็นเรื่องดึงดูดใจ อย่างไรก็ตาม เมื่อเป็นเรื่องของการบำรุงรักษา น้อยแต่มาก
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION