بشكل عام، المسند يعني عبارة تحدد ما إذا كانت القيمة صحيحة أم خاطئة. في المسندات البرمجة تعني وظائف ذات وسيطة واحدة ترجع قيمة منطقية. تم تحقيق مسند الواجهة الوظيفية في Java 8. وتعني كلمة "وظيفية" أنها تحتوي على طريقة مجردة واحدة فقط. يقبل الوسيطة ويعيد قيمة منطقية. في Java، يتم استخدام الواجهات الوظيفية للتعامل مع تعبيرات Lambda والمنشئات ومراجع الطريقة. عادةً ما يتم استخدام Java 8 Predicate لتطبيق مرشح على مجموعة من الكائنات. دعونا نلقي نظرة على تطبيقاته الرئيسية والأساليب المستخدمة على نطاق واسع، وكذلك حل بعض المسائل التدريبية.
لماذا يستخدم المطورون المسند
بشكل أساسي، يمكن للمطورين استخدام المسندات لأية مهام تتضمن تقييم العناصر بناءً على معايير محددة مسبقًا وإرجاع قيمة منطقية. فيما يلي أمثلة على المهام البسيطة التي يتعامل معها المطورون باستخدام المسندات:- تصفية مجموعة من الأعداد الصحيحة.
- فرز القوائم من خلال التأكد من توافق البيانات مع عدة شروط محددة مسبقاً (مثل تنظيم مجموعة من الأصناف من خلال تحديد شروط السعر والوزن).
- استخدام حزم المرافق في البرمجة المتزامنة.
بناء الجملة المسند في جافا
تم تقديم java.util.function.Predicate في Java 8 كطريقة بديلة للتعامل مع انطباعات التقييم في Lambda. العرض القياسي للواجهة هو Predicate<T> ، حيث T عبارة عن وسيطة واحدة تُرجع قيمة منطقية. تحتوي مسندات Java على اختبار أسلوب وظيفي (مجرد) (كائن) يقوم بتقييم هذا المسند على كائن معين.@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
جافا 8 طرق المسند
تحتوي واجهة المسند على عدد قليل من الأساليب.- يقوم الاختبار المنطقي (T t) بتقييم المسند على الوسيطة المحددة.
- المسند الافتراضي<T> و(المسند<? super T> أخرى) يُرجع مسندًا يمثل دائرة قصر منطقية AND لهذا المسند وآخر.
- المسند الافتراضي<T> أو يُرجع مسندًا مكونًا يمثل دائرة قصر منطقية OR لهذا المسند وآخر.
- الافتراضي Predicate<T> negate() يُرجع مسندًا معاكسًا لهذا المسند منطقيًا.
- الافتراضي Predicate<T> isEqual(Object targetRef) يُرجع نتيجة الاختبار إذا كانت الوسيطتان متساويتين وفقًا لـ Objects.equals(Object, Object) .
اختبار منطقي(Tر)
هذه طريقة وظيفية لمسندات Java التي تقوم بتقييم ما إذا كانت وسيطة معينة تفي بشرط المسند أم لا. مثال: هنا نقوم بإنشاء بالغ أصلي لكل شخص يبلغ من العمر 18 عامًا أو أكثر. تحصل طريقة test() على قيمة عددية وتتحقق منها.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 عامًا باستخدام و() . دعونا نستخدم predicate.add () ونكتب مسند Java مع lambda لهذه الشروط: إذا كان الشرط صحيحًا، فسيقوم التطبيق بإرجاع العبارة التالية: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() لجمع كافة القيم التي لا تتوافق مع المعايير المحددة مسبقًا. على سبيل المثال: إذا كنت تريد فرز فئة "الطماطم" والعثور على جميع الإدخالات التي ليست "حمراء"، فيمكنك كتابة مسند وإجراء فحص سريع للتسلسل بأكمله. حاول كتابة الكود الخاص بهذا بنفسك وتحقق منه مقابل الحل بمجرد الانتهاء.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))
}
}
الإخراج هو:
خطأ صحيح
المسند الثابت يساوي (الكائن targetRef)
تعتبر هذه الطريقة مفيدة للغاية إذا كنت تريد تحديد ما إذا كان هناك كائنان مساويان لقيمة محددة كمعلمة للكائن Objects.equals(). تعتبر هذه الطريقة مفيدة بشكل خاص إذا كنت بحاجة إلى مقارنة نتائج الاختبارات المماثلة. على سبيل المثال: لنفترض أنك تقارن بين عربتين من الكمثرى وتريد التأكد مما إذا كان كلاهما يحتوي على ثمار ذات وزن ولون قياسيين. في هذه الحالة، المسند الثابت 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"));
}
}
إذا كان الكائن الذي تقوم بتحليله يتوافق مع الشروط القياسية، فستعود الدالة صحيحة. الإخراج هو:
صحيح كاذب
جافا IntPredicate
Java IntPredicate عبارة عن واجهة وظيفية، لذا يمكنك استخدامها كهدف مهمة لتعبير lambda أو مرجع الأسلوب. يعمل 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
كتابة المسندات النظيفة في جافا
تعد Java Predicates عملية للغاية وممتعة للعمل معها. ومع ذلك، ما لم تكن على دراية بكيفية تأثير تعبيرات لامدا التي تكتبها على التعليمات البرمجية، فهناك خطر تقليل إمكانية صيانة التعليمات البرمجية مع المسندات الفوضوية. فيما يلي بعض الممارسات البسيطة التي ستساعدك على ضمان سهولة إدارة وقراءة واجهاتك الوظيفية.- لا تكرر نفسك - لا تقم بتكوين المسندات باستخدام Java بقيم وأساليب وشروط متكررة أكثر من مرة. بهذه الطريقة، تضيع وقتك الإنتاجي وتجعل التعليمات البرمجية فوضوية.
- افصل المسندات عن كود التطبيق لضمان قابلية الاختبار. بخلاف ذلك، قم بإنشاء جدول اختبار الوحدة الأصلية والتزم به.
- استخدم الواردات وأنماط التكوين لضمان عدم تضخم فصولك الدراسية وسهولة إدارتها.
- فكر في نقل مسندات Java إلى فئات Helper - وبهذه الطريقة، يمكنك تحسين إمكانية إعادة استخدام التعليمات البرمجية الخاصة بك وتسهيل الصيانة.
- سهولة القراءة - كلما أمكن ذلك، فضل العبارات المكونة من سطر واحد على المسندات المعقدة. قد يكون من المغري إظهار فهمك للواجهات الوظيفية المعقدة. ومع ذلك، عندما يتعلق الأمر بالصيانة، فالأقل هو الأكثر.
GO TO FULL VERSION