به طور کلی محمول به معنای عبارتی است که تعیین می کند یک مقدار می تواند درست یا نادرست باشد. در برنامهنویسی محمولها میانگین توابع با یک آرگومان هستند که مقدار بولی را برمیگردانند. گزاره رابط تابعی در جاوا 8 محقق شد. یک آرگومان را می پذیرد و یک Boolean برمی گرداند. در جاوا، رابط های کاربردی برای مدیریت عبارات لامبدا، سازنده ها و مراجع روش استفاده می شود. معمولاً از Java 8 Predicate برای اعمال فیلتر برای مجموعه ای از اشیاء استفاده می شود. بیایید نگاهی به کاربردهای اصلی و روش های پرکاربرد آن و همچنین حل برخی از مشکلات تمرینی بیندازیم.

چرا توسعه دهندگان از Predicate استفاده می کنند
اساساً، توسعهدهندگان میتوانند از گزارهها برای هر کاری که شامل ارزیابی آیتمها بر اساس معیارهای از پیش تعریفشده و برگرداندن یک مقدار بولی است، استفاده کنند. در اینجا نمونه هایی از کارهای ساده ای است که توسعه دهندگان با استفاده از گزاره ها انجام می دهند:- فیلتر کردن مجموعه ای از اعداد صحیح
- مرتب سازی لیست ها با اطمینان از اینکه داده ها با چندین شرایط از پیش تعریف شده مطابقت دارند (مانند سازماندهی طیف وسیعی از اقلام با تنظیم شرایط قیمت و وزن).
- استفاده از بسته های کاربردی در برنامه نویسی همزمان
نحو محمول در جاوا
java.util.function.Predicate در جاوا 8 به عنوان روشی جایگزین برای مدیریت برداشت های ارزیابی در لامبدا معرفی شد. نمای استاندارد اینترفیس Predicate<T> است ، که در آن T یک آرگومان منفرد است که مقدار بولی را برمی گرداند. گزاره های جاوا دارای یک روش تابعی (انتزاعی) تست (Object) هستند که این گزاره را روی یک شی معین ارزیابی می کند.
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
در اینجا مثالی از نوشتن یک Predicate ساده است که اعداد صحیح را بر اساس شرایط "بیشتر از"، "کمتر از" فیلتر می کند.
// 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. یک مثال دیگر با Predicate در filter() . Predicate به فیلتر کردن همه بزرگسالان از فهرست سنی کمک می کند.
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
رابط Predicate چندین روش دارد.- آزمون بولی (T t) گزاره را در آرگومان داده شده ارزیابی می کند.
- گزاره پیشفرض<T> و (گزاره <? super T> دیگر) گزارهای را برمیگرداند که یک AND منطقی اتصال کوتاه این گزاره و دیگری را نشان میدهد.
- گزاره پیشفرض<T> یا یک گزاره مرکب را برمیگرداند که یک OR منطقی اتصال کوتاه از این گزاره و دیگری را نشان میدهد.
- پیشفرض Predicate<T> negate() گزارهای را برمیگرداند که از نظر منطقی مخالف این گزاره است.
- اگر دو آرگومان مطابق Objects.equals (Object، Object) برابر باشند، Predicate<T> isEqual(Object targetRef) پیشفرض، نتیجه آزمایش را برمیگرداند .
آزمون بولی (T t)
این یک روش کاربردی برای گزاره های جاوا است که ارزیابی می کند که آیا یک آرگومان داده شده شرایط یک گزاره را برآورده می کند یا خیر. مثال: در اینجا ما یک گزاره بزرگسال برای همه کسانی که 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 است نادرست خواهد بود. در مورد سناریوی دوم و سوم، شرایط فراهم است بنابراین بازگشت واقعی خواهد بود.
دروغ درست درست
Predicate.and() پیش فرض
این متد عملگر "and" را نشان می دهد. به همین دلیل است که اگر یکی از محمول های داده شده با یک شرط تعیین شده مطابقت نداشته باشد، دیگری ارزیابی نمی شود. مثال: بیایید گزارهها را در جاوا بنویسیم، و همه افرادی را که از قبل بالغ هستند اما کمتر از 65 سال دارند با استفاده از and() فیلتر کنیم . بیایید از predicate.add () استفاده کنیم و یک گزاره جاوا با لامبدا برای این شرایط بنویسیم: اگر شرط درست باشد، برنامه عبارت زیر را برمیگرداند:
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() پیش فرض
متد 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 برای جمع آوری تمام مقادیری که با معیارهای از پیش تعریف شده مطابقت ندارند استفاده می شود. مثال: اگر میخواهید کلاس «گوجهفرنگی» را مرتب کنید و همه ورودیهایی که «قرمز» نیستند را پیدا کنید، میتوانید یک Predicate بنویسید و به سرعت کل دنباله را اسکن کنید. سعی کنید کد این یکی را خودتان بنویسید و پس از اتمام کار، آن را با راه حل بررسی کنید.
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"));
}
}
اگر شیء مورد تجزیه و تحلیل شما با شرایط استاندارد مطابقت داشته باشد، تابع true خواهد شد. خروجی این است:
غلط درست
جاوا IntPredicate
Java IntPredicate یک رابط کاربردی است، بنابراین می توانید از آن به عنوان هدف انتساب برای عبارت لامبدا یا مرجع روش استفاده کنید. IntPredicate بر روی یک عدد صحیح عمل می کند و یک مقدار محمول را بر اساس یک شرط برمی گرداند. مانند Interface Predicate، IntPredicate متدهای test() , and() , negate() , or() دارد . در اینجا یک مثال از 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
نوشتن محمولات پاک در جاوا
جاوا گزاره ها بسیار کاربردی و سرگرم کننده هستند. با این حال، مگر اینکه مراقب باشید که عبارات لامبدا چگونه روی کد تأثیر میگذارند، خطر کاهش قابلیت نگهداری کد با محمولات نامرتب وجود دارد. در اینجا چند روش ساده وجود دارد که به شما کمک می کند اطمینان حاصل کنید که رابط های عملکردی شما به راحتی قابل مدیریت و خواندن هستند.- خودتان را تکرار نکنید - با جاوا گزاره هایی با مقادیر، روش ها و شرایط تکراری بیش از یک بار ننویسید. به این ترتیب، زمان مفید خود را تلف میکنید و کد را به هم میریزید.
- محمولات را از کد برنامه جدا کنید تا از آزمایش پذیری اطمینان حاصل کنید. به غیر از آن، یک برنامه آزمایش واحد محمول ایجاد کنید و به آن پایبند باشید.
- از الگوهای وارداتی و ترکیب بندی استفاده کنید تا مطمئن شوید که کلاس های شما پف نکرده و مدیریت آن آسان است.
- انتقال محمولات جاوا به کلاس های Helper را در نظر بگیرید – به این ترتیب، قابلیت استفاده مجدد کد خود را بهبود می بخشید و تعمیر و نگهداری را تسهیل می کنید.
- خوانایی - در صورت امکان، عبارات یک خطی را بر محمولات پیچیده ترجیح دهید. ممکن است وسوسه انگیز باشد که درک خود را از رابط های کاربردی پیچیده نشان دهید. با این حال، وقتی صحبت از تعمیر و نگهداری می شود، کمتر، بیشتر است.
GO TO FULL VERSION