Supplier وConsumer
إنتاج القيم واستهلاكها
Supplier وConsumer درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.
ما الذي تفعله Supplier
لا تأخذ Supplier<T> أي وسائط وتنتج قيمة من النوع T.
- طريقتها هي
T get(). - وهي مثالية لإنشاء القيم بشكل كسول أو مؤجل.
import java.util.function.Supplier;
public class Main {
public static void main(String[] args) {
Supplier<String> greeting = () -> "Hello!";
System.out.println(greeting.get());
}
}تتسم Suppliers بالكسل
لا تُنفَّذ التعليمة البرمجية داخل Supplier إلا عند استدعاء get. وهذا يجعل Suppliers مثالية للقيم الافتراضية المكلفة التي قد لا تحتاجون إليها أبدًا.
import java.util.function.Supplier;
public class Main {
public static void main(String[] args) {
Supplier<Integer> expensive = () -> {
System.out.println("computing...");
return 42;
};
System.out.println("before get");
System.out.println(expensive.get());
}
}Supplier للقيم الافتراضية
تقبل العديد من واجهات API كائنًا من نوع Supplier لكي تحسب القيمة عند الحاجة فقط، مثل Optional.orElseGet.
import java.util.Optional;
public class Main {
public static void main(String[] args) {
Optional<String> name = Optional.empty();
System.out.println(name.orElseGet(() -> "default"));
}
}ما الذي تفعله Consumer
تقبل Consumer<T> قيمة ولا تعيد أي شيء (void).
- طريقتها هي
void accept(T t). - وتُستخدم للآثار الجانبية مثل الطباعة أو التسجيل.
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
Consumer<String> printer = s -> System.out.println("Got: " + s);
printer.accept("data");
}
}Consumer مع forEach
أكثر موضع تصادفون فيه Consumer شيوعًا هو Iterable.forEach وStream.forEach.
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> items = List.of("a", "b", "c");
items.forEach(item -> System.out.println(item));
}
}تسلسل Consumers باستخدام andThen
يدعم Consumer الدالة andThen، التي تنفّذ دالتَي Consumer بالتتابع على المدخل نفسه.
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
Consumer<String> first = s -> System.out.println("upper: " + s.toUpperCase());
Consumer<String> second = s -> System.out.println("len: " + s.length());
first.andThen(second).accept("hello");
}
}BiConsumer لمدخلين
يقبل BiConsumer<T, U> وسيطين ولا يعيد شيئًا. ويستخدمه Map.forEach للتكرار على أزواج المفتاح والقيمة.
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, Integer> ages = Map.of("Ann", 30, "Bob", 25);
ages.forEach((name, age) -> System.out.println(name + "=" + age));
}
}مراجع الطرق بصفتها Consumers
يُعد مرجع طريقة مثل System.out::println كائن Consumer واضحًا.
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3);
nums.forEach(System.out::println);
}
}دمج Supplier وConsumer
يمكن لـ Supplier تمرير القيمة التي ينتجها مباشرةً إلى Consumer، لتشكيل تدفق بسيط من الإنتاج ثم الاستهلاك.
import java.util.function.Supplier;
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
Supplier<String> source = () -> "payload";
Consumer<String> sink = s -> System.out.println("received " + s);
sink.accept(source.get());
}
}إرجاع الكائنات من Supplier
تُنشئ المُنشئات مورّدات طبيعية باستخدام ClassName::new عندما لا تكون هناك حاجة إلى معاملات.
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
public class Main {
public static void main(String[] args) {
Supplier<List<String>> factory = ArrayList::new;
List<String> list = factory.get();
list.add("x");
System.out.println(list);
}
}الآثار الجانبية مقابل الدوال النقية
تذكّروا الفرق:
Supplier: لا يستقبل إدخالًا وينتج مخرجًا.Consumer: يستقبل إدخالًا ولا ينتج مخرجًا، بل يُحدث أثرًا جانبيًا.Function: يستقبل إدخالًا ويُرجع مخرجًا.
import java.util.function.Supplier;
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
Supplier<Integer> dice = () -> 4;
Consumer<Integer> show = n -> System.out.println("rolled " + n);
show.accept(dice.get());
}
}تحقّق سريع
ما الواجهة الوظيفية التي لا تستقبل أي معاملات وتُرجع قيمة؟
مراجعة
لقد أنتجتم القيم واستهلكتموها بطريقة وظيفية:
- تستخدم
Supplier<T>الدالةget()للإنتاج الكسول. - تستخدم
Consumer<T>الدالةaccept()لإحداث الآثار الجانبية، ويمكن ربطها باستخدامandThen. - تتعامل
BiConsumer<T,U>مع مدخلين، كما فيMap.forEach. - تجعل مراجع الدوال ومراجع المُنشئات الشيفرة أكثر اختصارًا.
الأسئلة الشائعة
هل درس «Supplier وConsumer» مجاني؟
نعم — نص درس «Supplier وConsumer» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.
ماذا ستتعلم في «Supplier وConsumer»؟
إنتاج القيم واستهلاكها تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «Supplier وConsumer»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- Function وBiFunction
- Supplier وConsumer
- Predicate والتركيب
- الواجهات الوظيفية المخصصة