قائمة الدلائل الفرعية باستخدام flatMap
لقد رأينا من قبل كيفية إدراج الملفات في دليل محدد. دعونا نلقي نظرة على كيفية اجتياز الدلائل الفرعية المباشرة للدليل المحدد (العمق هو 1)، وتنفيذ إصدار بسيط أولاً، ثم استخدام طريقة flatMap() الأكثر ملاءمة لتنفيذه.
نستخدم أولاً حلقة for تقليدية لاجتياز دليل محدد. إذا كانت هناك ملفات في الدليل الفرعي، فأضفها إلى القائمة، وإلا أضف الدليل الفرعي إلى القائمة. وأخيرا، قم بطباعة العدد الإجمالي لجميع الملفات. الكود أدناه - هذا الكود مخصص للوضع الصعب.
انسخ رمز الكود كما يلي:
قائمة الفراغات الثابتة العامةTheHardWay() {
List<File> files = new ArrayList<>();
File[] filesInCurrentDir = new File(".".listFiles();
ل(ملف الملف: filesInCurrentDir) {
File[] filesInSubDir = file.listFiles();
إذا (filesInSubDir!= فارغة) {
files.addAll(Arrays.asList(filesInSubDir));
} آخر {
files.add(file);
}
}
System.out.println("العدد: " + files.size())
}
نحصل أولاً على قائمة الملفات في الدليل الحالي ثم نجتازها. لكل ملف، إذا كان لديه ملفات فرعية، قم بإضافتها إلى القائمة. لا توجد مشكلة في هذا، ولكن هناك بعض المشكلات الشائعة: قابلية التغيير، وجنون العظمة من النوع الأساسي، والحتمية، وإسهاب الكود، وما إلى ذلك. هناك طريقة صغيرة تسمى flatMap () يمكنها حل هذه المشكلات.
كما يوحي الاسم، يتم تسوية هذه الطريقة بعد رسم الخرائط. يقوم بتعيين العناصر في المجموعة تمامًا مثل الخريطة (). ولكن على عكس طريقة الخريطة ()، فإن تعبير لامدا في طريقة الخريطة () يُرجع عنصرًا فقط، وما يتم إرجاعه هنا هو كائن دفق. لذلك تقوم هذه الطريقة بتسوية تدفقات متعددة وتعيين كل عنصر بداخلها إلى تدفق مسطح.
يمكننا استخدام flatMap() لإجراء عمليات مختلفة، ولكن المشكلة المطروحة توضح قيمتها. يحتوي كل دليل فرعي على قائمة أو دفق من الملفات، ونريد الحصول على قائمة الملفات الموجودة في جميع الدلائل الفرعية ضمن الدليل الحالي.
قد تكون بعض الأدلة فارغة أو لا تحتوي على عناصر فرعية. في هذه الحالة، نقوم بلف الدليل أو الملف الفارغ في كائن دفق. إذا أردنا تجاهل ملف، فيمكن لأسلوب flatMap() في JDK أيضًا التعامل مع الملفات الفارغة بشكل جيد جدًا؛ وسيقوم بدمج مرجع فارغ في الدفق كمجموعة فارغة. دعونا نلقي نظرة على استخدام طريقة flatMap().
انسخ رمز الكود كما يلي:
الفراغ الثابت العام BetterWay () {
قائمة <ملف> الملفات =
Stream.of(ملف جديد(".").listFiles())
.flatMap(file -> file.listFiles() == null ?
Stream.of(ملف): Stream.of(file.listFiles()))
.collect(toList());
System.out.println("العدد: " + files.size());
}
نحصل أولاً على دفق الملف الفرعي للدليل الحالي، ثم نستدعي طريقة flatMap () الخاصة به. ثم قم بتمرير تعبير لامدا إلى هذه الطريقة، والذي سيعيد دفقًا من الملفات الفرعية للملف المحدد. تقوم طريقة flatMap () بإرجاع مجموعة من الملفات في كافة الدلائل الفرعية للدليل الحالي. نستخدم طريقة التجميع () وطريقة toList () في Collectors لتجميعها في قائمة.
يُرجع تعبير lambda الذي نمرره إلى flatMap() ملفًا فرعيًا للملف. إذا لم يكن الأمر كذلك، فسيتم إرجاع دفق الملف. تقوم طريقة flatMap() بتعيين هذا الدفق بشكل أنيق إلى مجموعة من الدفقات، ثم تقوم بتسوية المجموعة وأخيرًا دمجها في دفق واحد.
تعمل طريقة flatMap() على تقليل الكثير من أعمال التطوير - فهي تجمع بين عمليتين متتاليتين، غالبًا ما تسمى الصفوف - في عملية واحدة أنيقة.
نحن نعرف بالفعل كيفية استخدام طريقة flatMap() لسرد جميع الملفات في دليل فرعي فوري. دعونا نراقب عمليات تعديل الملف.
مراقبة تعديلات الملفات
نحن نعرف بالفعل كيفية العثور على الملفات والأدلة، ولكن إذا أردنا تلقي رسائل سريعة عند إنشاء الملفات أو تعديلها أو حذفها، فهذا أيضًا بسيط جدًا. تعتبر هذه الآلية مفيدة جدًا لمراقبة التغييرات في الملفات الخاصة مثل ملفات التكوين وموارد النظام. دعنا نستكشف هذه الأداة المقدمة في Java 7، WatchService، والتي يمكن استخدامها لمراقبة تعديلات الملفات. العديد من الميزات التي نراها أدناه تأتي من JDK 7، ولكن التحسين الأكبر هنا هو الراحة التي توفرها التكرارات الداخلية.
لنكتب أولاً مثالاً لمراقبة تعديلات الملف في الدليل الحالي. تتوافق فئة المسار في JDK مع مثيل في نظام الملفات، وهو مصنع لخدمات المراقب. يمكننا تسجيل أحداث الإعلام لهذه الخدمة، مثل هذا:
انسخ رمز الكود كما يلي:
مسار المسار inal = Paths.get(".");
watchService النهائي watchService =
المسار.getFileSystem()
.newWatchService();
path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
System.out.println("الإبلاغ عن أي ملف تم تغييره خلال الدقيقة التالية...");
لقد قمنا بتسجيل WatchService لمراقبة التعديلات على الدليل الحالي. يمكنك استطلاع رأي WatchService هذا للحصول على عمليات تعديل الملفات الموجودة في الدليل، وسيقوم بإرجاع هذه التغييرات إلينا من خلال WatchKey. بمجرد حصولنا على المفتاح، يمكننا تكرار جميع أحداثه للحصول على تفاصيل تحديث الملف. لأنه قد يتم تعديل ملفات متعددة في نفس الوقت، قد ترجع عملية الاستقصاء أحداث متعددة. دعونا نلقي نظرة على رمز الاقتراع والاجتياز.
انسخ رمز الكود كما يلي:
Final WatchKey watchKey = watchService.poll(1, TimeUnit.MINUTES);
إذا (watchKey!= فارغة) {
watchKey.pollEvents()
.تدفق()
.forEach(حدث ->
System.out.println(event.context()));
}
كما ترون هنا، تظهر ميزات Java 7 وJava 8 في نفس الوقت. نقوم بتحويل المجموعة التي تم إرجاعها بواسطة pollEvents() إلى Java 8 Stream، ثم نستخدم المكرر الداخلي الخاص بها لطباعة معلومات التحديث التفصيلية لكل ملف.
لنقم بتشغيل هذا الرمز، ثم قم بتعديل ملف Sample.txt في الدليل الحالي لمعرفة ما إذا كان البرنامج يمكنه اكتشاف هذا التحديث.
انسخ رمز الكود كما يلي:
الإبلاغ عن أي ملف تم تغييره خلال الدقيقة التالية...
عينة.txt
عندما نقوم بتعديل هذا الملف، سيطالبك البرنامج بأنه تم تعديل الملف. يمكننا استخدام هذه الميزة لمراقبة التحديثات لملفات مختلفة ثم تنفيذ المهام المقابلة. بالطبع، يمكننا أيضًا تسجيل عمليات إنشاء الملفات أو حذفها فقط.
تلخيص
باستخدام تعبيرات lambda ومراجع الأساليب، تصبح المهام الشائعة مثل معالجة السلاسل والملفات وإنشاء مقارنات مخصصة أسهل وأكثر إيجازًا. تصبح الطبقات الداخلية المجهولة أنيقة، ويختفي التباين مثل ضباب الصباح بعد شروق الشمس. فائدة أخرى للبرمجة بهذا النمط الجديد هي أنه يمكنك استخدام مرافق JDK الجديدة لاجتياز الأدلة الكبيرة بكفاءة.
الآن أنت تعرف كيفية إنشاء تعبير لامدا وتمريره إلى إحدى الطرق. في الفصل التالي، سنقدم كيفية استخدام الواجهات الوظيفية وتعبيرات لامدا لتصميم البرامج.