ฉันกำลังอ่านโค้ดที่ใช้Predicate
ใน Java ฉันไม่เคยใช้Predicate
. มีใครช่วยแนะนำฉันเกี่ยวกับบทช่วยสอนหรือคำอธิบายแนวความคิดPredicate
และการนำไปใช้ใน Java ได้ไหม
Predicate
ฉันกำลังอ่านโค้ดที่ใช้Predicate
ใน Java ฉันไม่เคยใช้Predicate
. มีใครช่วยแนะนำฉันเกี่ยวกับบทช่วยสอนหรือคำอธิบายแนวความคิดPredicate
และการนำไปใช้ใน Java ได้ไหม
Predicate
คำตอบ:
ฉันสมมติว่าคุณกำลังพูดถึงcom.google.common.base.Predicate<T>
จากฝรั่ง
จาก API:
กำหนด
true
หรือfalse
ค่าสำหรับอินพุตที่กำหนด ตัวอย่างเช่นRegexPredicate
อาจใช้Predicate<String>
และส่งคืนจริงสำหรับสตริงใด ๆ ที่ตรงกับนิพจน์ทั่วไปที่กำหนด
โดยพื้นฐานแล้วนี่คือนามธรรม OOP สำหรับการboolean
ทดสอบ
ตัวอย่างเช่นคุณอาจมีวิธีการช่วยเหลือดังนี้
static boolean isEven(int num) {
return (num % 2) == 0; // simple
}
ตอนนี้ให้ a List<Integer>
คุณสามารถประมวลผลเฉพาะเลขคู่ดังนี้:
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
for (int number : numbers) {
if (isEven(number)) {
process(number);
}
}
ด้วยPredicate
การif
ทดสอบจะแยกออกเป็นประเภท สิ่งนี้ช่วยให้สามารถทำงานร่วมกับส่วนที่เหลือของ API ได้เช่นIterables
ซึ่งมีวิธีการยูทิลิตี้มากมายที่ใช้Predicate
ซึ่งมีวิธีการสาธารณูปโภคหลายอย่างที่ต้องใช้เวลา
ดังนั้นตอนนี้คุณสามารถเขียนสิ่งนี้:
Predicate<Integer> isEven = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return (number % 2) == 0;
}
};
Iterable<Integer> evenNumbers = Iterables.filter(numbers, isEven);
for (int number : evenNumbers) {
process(number);
}
โปรดทราบว่าตอนนี้สำหรับแต่ละลูปนั้นง่ายขึ้นมากโดยไม่ต้องif
ทดสอบ เรามาถึงระดับที่สูงขึ้นของการลบล้างโดยการกำหนดIterable<Integer> evenNumbers
โดยfilter
ใช้ a Predicate
.
Iterables.filter
Predicate
อนุญาตให้Iterables.filter
ทำหน้าที่เป็นสิ่งที่เรียกว่าฟังก์ชันลำดับที่สูงขึ้น ด้วยตัวมันเองสิ่งนี้มีข้อดีมากมาย ใช้List<Integer> numbers
ตัวอย่างข้างต้น สมมติว่าเราต้องการทดสอบว่าตัวเลขทั้งหมดเป็นบวกหรือไม่ เราสามารถเขียนสิ่งนี้:
static boolean isAllPositive(Iterable<Integer> numbers) {
for (Integer number : numbers) {
if (number < 0) {
return false;
}
}
return true;
}
//...
if (isAllPositive(numbers)) {
System.out.println("Yep!");
}
ด้วย a Predicate
และทำงานร่วมกับไลบรารีที่เหลือเราสามารถเขียนสิ่งนี้แทน:
Predicate<Integer> isPositive = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return number > 0;
}
};
//...
if (Iterables.all(numbers, isPositive)) {
System.out.println("Yep!");
}
หวังว่าตอนนี้คุณจะเห็นค่าใน abstractions ที่สูงขึ้นสำหรับรูทีนเช่น "กรององค์ประกอบทั้งหมดตามเพรดิเคตที่กำหนด" "ตรวจสอบว่าองค์ประกอบทั้งหมดตรงตามเพรดิเคตที่กำหนดหรือไม่" ฯลฯ ทำให้โค้ดดีขึ้น
แต่น่าเสียดายที่ Java ไม่ได้มีวิธีการชั้นแรก: คุณไม่สามารถผ่านวิธีรอบและIterables.filter
Iterables.all
แน่นอนคุณสามารถส่งผ่านวัตถุใน Java ได้ ดังนั้นPredicate
ประเภทจึงถูกกำหนดและคุณส่งผ่านอ็อบเจ็กต์ที่ใช้อินเทอร์เฟซนี้แทน
Predicate<Integer>
เมื่อเรามีF<Integer, Boolean>
สิ่งที่เหมือนกันแล้ว?
เพรดิเคตคือฟังก์ชันที่ส่งกลับค่าจริง / เท็จ (เช่นบูลีน) ซึ่งตรงข้ามกับประพจน์ซึ่งเป็นค่าจริง / เท็จ (เช่นบูลีน) ใน Java เราไม่สามารถมีฟังก์ชันแบบสแตนด์อโลนได้ดังนั้นจึงสร้างเพรดิเคตโดยการสร้างอินเทอร์เฟซสำหรับอ็อบเจ็กต์ที่แสดงถึงเพรดิเคตจากนั้นจึงมีคลาสที่ใช้อินเทอร์เฟซนั้น ตัวอย่างของอินเทอร์เฟซสำหรับเพรดิเคตอาจเป็น:
public interface Predicate<ARGTYPE>
{
public boolean evaluate(ARGTYPE arg);
}
จากนั้นคุณอาจมีการใช้งานเช่น:
public class Tautology<E> implements Predicate<E>
{
public boolean evaluate(E arg){
return true;
}
}
เพื่อให้เข้าใจแนวคิดที่ดีขึ้นคุณอาจต้องการอ่านเกี่ยวกับตรรกะลำดับที่หนึ่ง
แก้ไข
มีอินเทอร์เฟซPredicateมาตรฐาน( java.util.function.Predicate ) ที่กำหนดไว้ใน Java API เป็น Java 8 ก่อน Java 8 คุณอาจพบว่าสะดวกในการนำอินเตอร์เฟสcom.google.common.baseมาใช้ซ้ำจากฝรั่ง .
นอกจากนี้โปรดทราบว่าใน Java 8 นั้นง่ายกว่ามากในการเขียนเพรดิเคตโดยใช้ lambdas ตัวอย่างเช่นใน Java 8 ขึ้นไปเราสามารถส่งผ่านp -> true
ไปยังฟังก์ชันแทนที่จะกำหนดคลาสย่อย Tautology ที่มีชื่อเหมือนข้างต้น
คุณสามารถดูตัวอย่างjava docหรือตัวอย่างการใช้งาน Predicate ได้ที่นี่
โดยทั่วไปจะใช้เพื่อกรองแถวในชุดผลลัพธ์ตามเกณฑ์เฉพาะใด ๆ ที่คุณอาจมีและส่งคืนค่าจริงสำหรับแถวที่ตรงตามเกณฑ์ของคุณ:
// the age column to be between 7 and 10
AgeFilter filter = new AgeFilter(7, 10, 3);
// set the filter.
resultset.beforeFirst();
resultset.setFilter(filter);
การเพิ่มสิ่งที่Michealพูด:
คุณสามารถใช้ Predicate ดังต่อไปนี้ในการกรองคอลเลกชันใน java:
public static <T> Collection<T> filter(final Collection<T> target,
final Predicate<T> predicate) {
final Collection<T> result = new ArrayList<T>();
for (final T element : target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;
}
เพรดิเคตหนึ่งที่เป็นไปได้คือ:
final Predicate<DisplayFieldDto> filterCriteria =
new Predicate<DisplayFieldDto>() {
public boolean apply(final DisplayFieldDto displayFieldDto) {
return displayFieldDto.isDisplay();
}
};
การใช้งาน:
final List<DisplayFieldDto> filteredList=
(List<DisplayFieldDto>)filter(displayFieldsList, filterCriteria);
Predicate
หรือเปล่า? สิ่งที่คล้ายกัน? อย่างอื่นทั้งหมด?