عند التعلم مجموعة في Java ، تجدر الإشارة إلى أن مجموعة واجهة الجذر للتسلسل الهرمي تنفذ واجهة <T> ITERFAL (الموجودة في حزمة java.lang) ، والتي تسمح للكائنات بأن تصبح هدفًا لبيان "foreach". الطريقة الوحيدة في هذه الواجهة هي إعادة تكرار تكرار على مجموعة من عناصر T-type.
1
الواجهة: ITERATOR <T>
iterator الواجهة العامة <e> {boolean hasnext () ؛ E التالي () ؛ باطلة إزالة () ؛ }بالنظر إلى واجهة برمجة تطبيقات واجهة Iterator ، يمكنك أن تعرف أن هذا هو تكرار يكرر المجموعة. يسمح التكرار للمتصل بإزالة العناصر من المجموعة التي أشار إليها التكرار أثناء التكرار باستخدام دلالات محددة جيدًا.
تجدر الإشارة بشكل خاص إلى أن طريقة إزالة () التكرار هذه تستخدم: قم بإزالة العنصر الأخير الذي تم إرجاعه بواسطة Iterator من المجموعة التي أشار إليها Iterator (العملية الاختيارية). لا يمكن استدعاء هذه الطريقة إلا مرة واحدة لكل مكالمة بعد ذلك. إذا تم تعديل المجموعة التي أشار إليها التكرار بطرق أخرى غير استدعاء هذه الطريقة (إزالة الطريقة) عند التكرار ، فإن سلوك التكرار غير مؤكد. عند تصميم واجهة Iterator <T> ، أشار مصمم الواجهة إلى أنه عند التكرار ، إذا تم استدعاء طريقة إزالة () باستثناء ما يتم استدعاء التكرار ويتم تعديل المجموعة التي يشير إليها التكرار ، فسيؤدي ذلك إلى عواقب غير مؤكدة. ما هي العواقب اعتمادًا على التنفيذ المحدد للتكرار. استجابةً للمواقف المحتملة لهذه النتيجة غير المؤكدة ، تمت مواجهة أحدها عند التعلم ArrayList: يلقي Iterator استثناء ConcurrentModificationException. يتم عرض الاستثناءات المحددة في الكود التالي:
استيراد java.util.arraylist ؛ استيراد java.util.collection ؛ استيراد java.util.iterator ؛ الفئة العامة itaratortest {public static void main (string [] args) {collection <string> list = new ArrayList <string> () ؛ list.add ("Android") ؛ list.add ("iOS") ؛ list.add ("Windows Mobile") ؛ iterator <string> iterator = list.iterator () ؛ بينما (iterator.hasnext ()) {string lang = iterator.next () ؛ القائمة. remove (lang) ؛ // سوف يرمي ConcurrentModificationException}}} سوف يلقي هذا الرمز استثناء ConcurrentModificationException عند التشغيل ، لأننا لا نستخدم طريقة إزالة () التكرار لحذف العنصر أثناء تشغيل التكرار ، ولكن بدلاً من ذلك ، استخدم طريقة Remove () من ArrayList لتغيير المجموعة التي أشار إليها المؤلف. هذا ينتهك مبادئ تصميم التكرار ، لذلك يحدث استثناء.
الشذوذ المبلغ عنه هو كما يلي:
استثناء في الموضوع "الرئيسي" java.util.concurrentModificationexception
في java.util.arraylist $ ittr.checkforcomodification (ArrayList.java:859)
في java.util.arraylist $ ittr.next (ArrayList.java:831)
في text.itaratortest.main (itaratortest.java:17)
2. حلقة من أجل ECH و ITERATAR ITERATOR <T>
بدءًا من Java 5 ، هناك حلقة من أجل ECH في Java ، والتي يمكن استخدامها للحلق من خلال التجميع والمصفوفة. تتيح لك حلقات Foreach اجتياز المجموعة دون استدعاء طريقة HasNext () في حلقة بينما الحفاظ على الفهرس في الحلقة التقليدية ، أو استخدام Iterator /ListIrator (تطبيق Iterator في ArrayList). تقوم الحلقة من أجل EACH بتبسيط عملية اجتياز أي مجموعة أو صفيف. ومع ذلك ، هناك نقطتان للانتباه إليهما عند استخدام حلقات foreach.
الكائنات التي تستخدم حلقات foreach يجب أن تنفذ واجهة <T>
يرجى الاطلاع على المثال التالي:
استيراد java.util.arraylist ؛ الفئة العامة foreachtest1 {public static void main (string args []) {customCollection <string> myCollection = customCollection <Tring> () جديد ؛ mycollection.add ("java") ؛ mycollection.add ("scala") ؛ mycollection.add ("Groovy") ؛ // ماذا سيفعل هذا الرمز ، طباعة اللغة ، رمي استثناء أو // خطأ في وقت الترجمة لـ (لغة السلسلة: myCollection) {system.out.println (لغة) ؛ }} الفئة الخاصة CustomCollection <T> {private ArrayList <T> bucket ؛ CustomCollection () {bucket = new ArrayList () ؛ } size int public () {return bucket.size () ؛ } boolean public isempty () {return bucket.isempty () ؛ } يحتوي Boolean العام على (t o) {return bucket.contains (o) ؛ } add boolean public (t e) {return bucket.add (e) ؛ } إزالة منطقية عامة (t o) {return bucket.remove (o) ؛ }}} لن يتم تجميع الكود أعلاه ، لأن فئة CustomCollection في الكود لا تنفذ واجهة <T> ITERFAL ، والخطأ الذي تم الإبلاغ عنه خلال فترة الترجمة هو كما يلي:
استثناء في الموضوع "الرئيسي" java.lang.err: مشكلة التجميع التي لم يتم حلها:
لا يمكن التكرار إلا على صفيف أو مثيل من java.lang.iterable
في text.foreachtest1.main (foreachtest1.java:15)
في الواقع ، ليست هناك حاجة للانتظار حتى التجميع للعثور على خطأ. سيعرض Eclipse خطأً في حلقة Foreach بعد انتهاء الكود: لا يمكن التكرار إلا على صفيف أو مثيل Java.lang.iterable
يمكن تأكيده مرة أخرى من المثال أعلاه على أن حلقة foreach قابلة للتطبيق فقط على الكائنات التي تنفذ واجهة <T> ITERFAL. نظرًا لأن جميع فئات التجميع المدمجة تنفذ واجهة java.util.collection وقد ورثت أمرًا غير مرغوب فيه ، من أجل حل المشكلة أعلاه ، يمكنك اختيار تمكين CustomCollection لتنفيذ واجهة التجميع أو الوراثة الملخص. الحل كما يلي:
استيراد java.util.abstractCollection ؛ استيراد java.util.arraylist ؛ استيراد java.util.iterator ؛ الفئة العامة foreachtest {public static void main (string args []) {customCollection <string> myCollection = customCollection <string> () ؛ mycollection.add ("java") ؛ mycollection.add ("scala") ؛ mycollection.add ("Groovy") ؛ لـ (لغة السلسلة: myCollection) {system.out.println (لغة) ؛ }} الفئة الثابتة الخاصة CustomCollection <T> يمتد AbstractCollection <T> {private ArrayList <T> bucket ؛ CustomCollection () {bucket = new ArrayList () ؛ } size int public () {return bucket.size () ؛ } boolean public isempty () {return bucket.isempty () ؛ } يحتوي المنطق العام على (كائن O) {return bucket.contains (o) ؛ } add boolean public (t e) {return bucket.add (e) ؛ } إزالة منطقية عامة (كائن O) {return bucket.remove (o) ؛ } Override Public Iterator <T> iterator () {// todo method method method stub bucket.iterator () ؛ }}}2. يتم تنفيذ التنفيذ الداخلي لحلقة foreach أيضًا بواسطة ITERATOR.
للتحقق من حقيقة أن حلقة foreach تستخدم ITERATOR كتطبيق داخلي ، ما زلنا نستخدم المثال الأولي لهذه المقالة للتحقق من:
الفئة العامة itaratortest {public static void main (string [] args) {collection <string> list = new ArrayList <String> () ؛ list.add ("Android") ؛ list.add ("iOS") ؛ list.add ("Windows Mobile") ؛ // example1 // iterator <string> iterator = list.iterator () ؛ // بينما (iterator.hasNext ()) {// string lang = iterator.next () ؛ // list.remove (lang) ؛ //} // مثال 2 لـ (لغة السلسلة: قائمة) {list.remove (لغة) ؛ }}} تم الإبلاغ عن استثناء عندما يعمل البرنامج:
استثناء في الموضوع "الرئيسي" java.util.concurrentModificationexception
في java.util.arraylist $ ittr.checkforcomodification (ArrayList.java:859)
في java.util.arraylist $ ittr.next (ArrayList.java:831)
في text.itaratortest.main (itaratortest.java:22)
يوضح هذا الاستثناء فقط أن الحلقة الخاصة بـ EACH تستخدم ITERATOR للتكرار من خلال المجموعة ، والتي تسمي أيضًا iterator.next () ، والتي تتحقق من (العنصر) الذي يغير ويلمي concurrentModificationException.
تلخيص:
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.