الجديد في Java 12: The Teeing Collector

في هذه المقالة ، سوف نلقي نظرة على جامع جديد تم تقديمه في Java 12. لم يتم الإعلان عن هذه الوظيفة الجديدة في JEP الرسمي ، حيث كان طلب تغيير بسيط بعنوان " Create Collector ، والذي يدمج نتائج جامعين آخرين ". وهي مصممة للجمع بين نتائج اثنين من هواة جمع العملات.


جميع مثيرة للاهتمام - تحت خفض


إذا كنت لا تزال لا تعرف ما هي جامعي
المجمّعون عبارة عن فصول خاصة تستخدم لتحويل دفق إلى بنية بيانات أخرى. على سبيل المثال ، في list :
 list = Stream.of(1,2,3).collect(Collectors.toList()); //     1, 2  3 

هذا مثال عديم الفائدة ، لأنه ينشئ دفقًا جديدًا ويحوله على الفور. ويعتقد أن تظهر استخدام جامعي

الوثائق


انقر هنا لعرض Collectors#teeing . حسب الوثائق الرسمية:
"... تقوم بإرجاع أداة تجميع تتكون من جامعي مرؤوسين. تتم معالجة كل عنصر يتم نقله إلى المجمع الناتج عن طريق كلا المجمعين المرتبين ، ثم يتم دمج نتائجهم باستخدام وظيفة خاصة تربطهم بالنتيجة النهائية. "
الأصلي
"... تُرجع أداة تجميع مجمعة من مجمعين متلقين للمعلومات. كل عنصر تم تمريره إلى المجمع الناتج يتم معالجته بواسطة كلا المجمعين المتلقين للمعلومات ، ثم يتم دمج نتائجهم باستخدام دالة الدمج المحددة في النتيجة النهائية."
رأس الطريقة:

 static <T, R1, R2, R> Collector<T, ?, R> teeing( Collector<? super T, ?, R1> downstream1, Collector<? super T, ?, R2> downstream2, BiFunction<? super R1, ? super R2, R> merger) 

حقيقة مثيرة للاهتمام


هذا هو نقطة الإنطلاق (teeing من الإنجليزية):



جاء Teeing من نقطة الإنطلاق. وفقًا لـ Wikipedia ، "نقطة الإنطلاق هي التركيب الأكثر شيوعًا (ربط جزء من خط أنابيب ، مترجم تقريبًا) يستخدم لدمج [أو تقسيم] دفق سائل (في هذه الحالة ، نعني الدفق ، الدفق - الدفق / الدفق ، مترجم التعليقات)."
تم اقتراح أسماء أخرى: التشريح (القسمة على 2_ الأجزاء) ، الطباعة على الوجهين ، التشعب (القسمة) ، النسخ المتماثل ، fanout (القسمة) ، التنصت ، الضغط ، التجميع ، ToToth ، ثم التنقيب البيولوجي ، التوسيع (الامتداد) ، التفرع ، إلخ.
جميع البدائل التي تم تقييمها بواسطة مطوري Core يمكن العثور عليها هنا .

أمثلة الاستخدام


قمت بتجميع ثلاثة أمثلة لاستخدام الكود بمستويات مختلفة من التعقيد.

قائمة الضيوف


نقوم باستخراج نوعين مختلفين من المعلومات من قائمة الكائنات في الدفق. يجب على كل ضيف قبول الدعوة ويمكنه قيادة الأسرة. نريد أن نعرف من أكد الحجز والعدد الإجمالي للمشاركين (بما في ذلك الضيوف وأفراد الأسرة).

 var result = Stream.of( // Guest(String name, boolean participating, Integer participantsNumber) new Guest("Marco", true, 3), new Guest("David", false, 2), new Guest("Roger",true, 6)) .collect(Collectors.teeing( //  ,    ,    Collectors.filtering(Guest::isParticipating, //        Collectors.mapping(o -> o.name, Collectors.toList())), //  ,       Collectors.summingInt(Guest::getParticipantsNumber), //      , //    EventParticipation::new )); System.out.println(result); //  // EventParticipation { guests = [Marco, Roger], // total number of participants = 11 } 


ضيف
 class Guest { private String name; private boolean participating; private Integer participantsNumber; public Guest(String name, boolean participating, Integer participantsNumber) { this.name = name; this.participating = participating; this.participantsNumber = participantsNumber; } public boolean isParticipating() { return participating; } public Integer getParticipantsNumber() { return participantsNumber; } } 


EventParticipation
 class EventParticipation { private List<String> guestNameList; private Integer totalNumberOfParticipants; public EventParticipation(List<String> guestNameList, Integer totalNumberOfParticipants) { this.guestNameList = guestNameList; this.totalNumberOfParticipants = totalNumberOfParticipants; } @Override public String toString() { return "EventParticipation { " + "guests = " + guestNameList + ", total number of participants = " + totalNumberOfParticipants + " }"; }} 


تصفية الأسماء في قائمتين مختلفتين


في هذا المثال ، نقسم مجموعة الأسماء إلى قائمتين وفقًا للمرشح.

 var result = Stream.of("Devoxx", "Voxxed Days", "Code One", "Basel One", "Angular Connect") .collect(Collectors.teeing( //   Collectors.filtering(n -> n.contains("xx"), Collectors.toList()), //   Collectors.filtering(n -> n.endsWith("One"), Collectors.toList()), //  -       (List<String> list1, List<String> list2) -> List.of(list1, list2) )); System.out.println(result); // -> [[Devoxx, Voxxed Days], [Code One, Basel One]] 

عد وإضافة دفق من الأرقام


ربما تكون قد شاهدت مثالًا مشابهًا يظهر على المدونات يجمع بين المجموع والعدد للحصول على المتوسط. هذا المثال لا يتطلب Teeing ، ويمكنك ببساطة استخدام AverageInt وجامع بسيط.

يستخدم المثال التالي دالات من Teeing لإرجاع قيمتين:

 var result = Stream.of(5, 12, 19, 21) .collect(Collectors.teeing( //   Collectors.counting(), //   Collectors.summingInt(n -> Integer.valueOf(n.toString())), // : (count, sum) -> new Result(count, sum); Result::new )); System.out.println(result); // -> {count=4, sum=57} 

نتيجة
 class Result { private Long count; private Integer sum; public Result(Long count, Integer sum) { this.count = count; this.sum = sum; } @Override public String toString() { return "{" + "count=" + count + ", sum=" + sum + '}'; }} 


فخ ممكن


Map.Entry

تستخدم العديد من الأمثلة Map.Entry لتخزين نتيجة BiFunction . يرجى عدم القيام بذلك لأنه لا يمكنك تخزين الوسيطة الأخيرة في Map . لا يوجد كائن قياسي في Java Core لتخزين قيمتين - سيكون عليك إنشائه بنفسك.

كل شيء عن ميزات جافا الجديدة 12


يمكنك معرفة المزيد من المعلومات والحقائق المثيرة للاهتمام حول Java 12 في هذا العرض التقديمي .

المقتنيات الناجحة!

Source: https://habr.com/ru/post/ar445622/


All Articles