JavaRush /جاوا بلاگ /Random-SD /هر هڪ لوپ لاءِ ۽ هر هڪ لوپ لاءِ: هڪ ڪهاڻي جو مون ڪيئن ورج...
Viacheslav
سطح

هر هڪ لوپ لاءِ ۽ هر هڪ لوپ لاءِ: هڪ ڪهاڻي جو مون ڪيئن ورجايو، ورجايو ويو، پر ٻيهر نه ڪيو ويو

گروپ ۾ شايع ٿيل

تعارف

لوپ پروگرامنگ ٻولين جي بنيادي جوڙجڪ مان هڪ آهن. مثال طور، Oracle ويب سائيٽ تي هڪ سيڪشن آهي “ Lesson: Language Basics ”، جنهن ۾ loops ۾ هڪ الڳ سبق آهي “ The for Statement ”. اچو ته بنيادي ڳالهين کي تازو ڪريون: لوپ ٽن اظهارن (بيانن) تي مشتمل آهي: شروعات (شروعات)، شرط (ختم ٿيڻ) ۽ واڌارو (وڌائي):
هر هڪ لوپ لاءِ ۽ لاءِ: هڪ ڪهاڻي انهي بابت ڪيئن مون ٻيهر بيان ڪيو، بار بار ڪيو، پر ٻيهر نه ڪيو - 1
دلچسپ ڳالهه اها آهي ته، اهي سڀئي اختياري آهن، مطلب ته اسان ڪري سگهون ٿا، جيڪڏهن اسان چاهيون ٿا، لکي ٿو:
for (;;){
}
سچ، هن معاملي ۾ اسان کي هڪ لامحدود لوپ حاصل ڪندو، ڇاڪاڻ ته اسان لوپ مان نڪرڻ (ختم ٿيڻ) لاءِ شرط بيان نٿا ڪريون. شروعاتي اظهار صرف هڪ ڀيرو جاري ڪيو ويو آهي، مڪمل لوپ تي عمل ڪرڻ کان اڳ. اهو هميشه ياد رکڻ جي قابل آهي ته هڪ چڪر جو پنهنجو دائرو آهي. هن جو مطلب اهو آهي ته شروعات ، ختم ٿيڻ ، واڌارو ۽ لوپ جسم ساڳيو متغير ڏسي ٿو. دائرو هميشه گھمڻ واري ڪنگڻ استعمال ڪندي طئي ڪرڻ آسان آهي. بریکٹ جي اندر موجود هر شيءِ بریکٹس کان ٻاهر نظر نه ايندي آهي، پر بریکٹس کان ٻاهر هر شيءِ بریکٹس اندر نظر ايندي آهي. شروعات صرف هڪ اظهار آهي. مثال طور، هڪ متغير کي شروع ڪرڻ جي بدران، توهان عام طور تي هڪ طريقو سڏي سگهو ٿا جيڪو ڪجھ به واپس نه ڪندو. يا صرف ان کي ڇڏي ڏيو، پهرين سيميڪولن کان اڳ خالي جاء ڇڏي. ھيٺ ڏنل بيان بيان ڪري ٿو ختم ٿيڻ واري حالت . جيستائين اھو سچ آھي ، لوپ تي عمل ڪيو ويندو آھي. ۽ جيڪڏھن غلط آھي ، ھڪڙو نئون ورجائي شروع نه ٿيندو. جيڪڏهن توهان هيٺ ڏنل تصوير تي نظر رکون ٿا، اسان کي گڏ ڪرڻ دوران هڪ غلطي ملي ٿي ۽ IDE شڪايت ڪندو: لوپ ۾ اسان جو اظهار ناقابل رسائي آهي. جيئن ته اسان وٽ لوپ ۾ ھڪڙو اکر نه ھوندو، اسان فوري طور تي نڪرنداسين، ڇاڪاڻ ته ڪوڙو:
هر هڪ لوپ لاءِ ۽ هر هڪ لوپ لاءِ: هڪ ڪهاڻي ته ڪيئن مون ورجايو، بار بار ڪيو، پر ٻيهر نه ڪيو - 2
اهو ختم ٿيڻ واري بيان ۾ اظهار تي نظر رکڻ جي قابل آهي : اهو سڌو سنئون اهو طئي ڪري ٿو ته ڇا توهان جي درخواست ۾ لامحدود لوپ هوندا. واڌارو آسان ترين اظهار آهي. اهو لوپ جي هر ڪامياب ورهاڱي کان پوء عمل ڪيو ويندو آهي. ۽ اهو اظهار پڻ ڇڏي سگهجي ٿو. مثال طور:
int outerVar = 0;
for (;outerVar < 10;) {
	outerVar += 2;
	System.out.println("Value = " + outerVar);
}
جيئن ته توهان مثال مان ڏسي سگهو ٿا، لوپ جي هر ورهاڱي ۾ اسان 2 جي واڌ ۾ واڌ ڪنداسين، پر صرف ان وقت تائين جيستائين قيمت 10 کان گهٽ آهي. ان کان علاوه، ڇاڪاڻ ته واڌ واري بيانouterVar ۾ اظهار اصل ۾ صرف هڪ اظهار آهي، اهو ڪجھ به شامل ڪري سگھي ٿو. تنهن ڪري، ڪو به هڪ واڌارو جي بدران گهٽتائي استعمال ڪرڻ کان منع ڪري ٿو، يعني. قدر گھٽائڻ. توهان کي هميشه واڌ جي لکڻ جي نگراني ڪرڻ گهرجي. اڳ ۾ واڌارو انجام ڏئي ٿو ۽ پوءِ هڪ اسائنمينٽ، پر جيڪڏهن مٿين مثال ۾ اسان مخالف لکنداسين ته اسان کي هڪ لامحدود لوپ ملندو، ڇاڪاڻ ته متغير ڪڏهن به تبديل ٿيل قدر حاصل نه ڪندو: هن صورت ۾ اهو حساب ڪتاب کان پوءِ ڪيو ويندو. رستي جي ذريعي، اهو ساڳيو آهي ڏسڻ جي واڌاري سان . مثال طور، اسان وٽ هڪ لوپ هو: +=outerVar=+++
String[] names = {"John","Sara","Jack"};
for (int i = 0; i < names.length; ++i) {
	System.out.println(names[i]);
}
چڪر ڪم ڪيو ۽ ڪو مسئلو نه هو. پر پوءِ ريفيڪٽرنگ وارو ماڻهو آيو. هن واڌ کي سمجهي نه سگهيو ۽ صرف هن ڪيو:
String[] names = {"John","Sara","Jack"};
for (int i = 0; i < names.length;) {
	System.out.println(names[++i]);
}
جيڪڏهن واڌ جي نشاني قيمت جي سامهون ظاهر ٿئي ٿي، ان جو مطلب اهو آهي ته اهو پهريون ڀيرو وڌندو ۽ پوء انهي جاء تي واپس ايندو جتي اهو اشارو ڪيو ويو آهي. هن مثال ۾، اسان فوري طور تي انڊيڪس 1 تي عنصر کي صف مان ڪڍڻ شروع ڪنداسين، پهرين کي ڇڏڻ. ۽ پوء انڊيڪس 3 تي اسان غلطي سان حادثو ڪنداسين " java.lang.ArrayIndexOutOfBoundsException ". جئين توهان اندازو ڪيو هوندو، اهو ڪم صرف اڳ ۾ ئي ڪيو ويو آهي ڇاڪاڻ ته واڌ کي سڏيو ويندو آهي ٻيهر ختم ٿيڻ کان پوء. جڏهن هن اظهار کي منتقلي ڏانهن منتقل ڪيو، هر شيء ڀڄي وئي. جيئن ته اهو نڪتو، جيتوڻيڪ هڪ سادي لوپ ۾ توهان هڪ گندگي ٺاهي سگهو ٿا) جيڪڏهن توهان وٽ هڪ صف آهي، ٿي سگهي ٿو ته سڀني عناصر کي ظاهر ڪرڻ لاء ڪجهه آسان طريقو آهي؟
هر هڪ لوپ لاءِ ۽ هر هڪ لوپ لاءِ: هڪ ڪهاڻي ته ڪيئن مون ورجايو، بار بار ڪيو، پر ٻيهر نه ڪيو - 3

هر لوپ لاء

جاوا 1.5 سان شروع ڪندي، جاوا ڊولپرز اسان کي for each loopگائيڊ ۾ Oracle سائيٽ تي بيان ڪيل هڪ ڊزائن ڏني آهي جنهن کي " The For-Each Loop " يا ورزن 1.5.0 لاءِ سڏيو ويندو آهي . عام طور تي، اهو هن طرح نظر ايندو:
هر هڪ لوپ لاءِ ۽ هر هڪ لوپ لاءِ: هڪ ڪهاڻي ته ڪيئن مون ورجايو، بار بار ڪيو، پر ٻيهر نه ڪيو - 4
توھان پڙھي سگھوٿا ھن تعمير جي وضاحت جاوا ٻوليءَ جي وضاحت (JLS) ۾ پڪ ڪرڻ لاءِ ته اھو جادو نه آھي. ھن تعمير کي باب ۾ بيان ڪيو ويو آھي " 14.14.2. بيان لاء وڌايو ويو ". جئين توهان ڏسي سگهو ٿا، هر لوپ لاء استعمال ڪري سگهجي ٿو arrays ۽ انهن سان جيڪي لاڳو ڪن ٿيون java.lang.Iterable انٽرفيس . اهو آهي، جيڪڏهن توهان واقعي چاهيو ٿا، توهان لاڳو ڪري سگهو ٿا java.lang.Iterable انٽرفيس ۽ هر لوپ لاءِ توهان جي ڪلاس سان استعمال ڪري سگهجي ٿو. توهان فوري طور تي چوندا، "ٺيڪ آهي، اهو هڪ ٻيهر قابل اعتراض آهي، پر هڪ صف هڪ اعتراض ناهي. ترتيب ڏيو." ۽ توهان غلط ٿي ويندا، ڇاڪاڻ ته ... جاوا ۾، arrays متحرڪ طور تي ٺاهيل شيون آهن. ٻولي جي وضاحت اسان کي ٻڌائي ٿي: " جاوا پروگرامنگ ٻولي ۾، arrays شيون آهن ." عام طور تي، arrays JVM جادوء جو ٿورڙو آهن، ڇاڪاڻ ته ... صفا اندروني طور تي ڪيئن ٺهيل آهي نامعلوم آهي ۽ جاوا ورچوئل مشين جي اندر ڪٿي واقع آهي. ڪو به دلچسپي وٺندڙ جواب پڙهي سگهي ٿو اسٽيڪ اوور فلو تي: " جاوا ۾ ايري ڪلاس ڪيئن ڪم ڪندو آهي؟ " اهو ظاهر ٿئي ٿو ته جيڪڏهن اسان هڪ صف استعمال نه ڪري رهيا آهيون، پوء اسان کي ڪجهه استعمال ڪرڻ گهرجي جيڪو لاڳو ڪري ٿو Iterable . مثال طور:
List<String> names = Arrays.asList("John", "Sara", "Jack");
for (String name : names) {
	System.out.println("Name = " + name);
}
هتي توهان صرف ياد ڪري سگهو ٿا ته جيڪڏهن اسان مجموعا ( java.util.Collection ) استعمال ڪندا آهيون، ان جي مهرباني، اسان کي بلڪل Iterable حاصل ٿيندو . جيڪڏهن ڪنهن شئي جو هڪ ڪلاس آهي جيڪو Iterable کي لاڳو ڪري ٿو، اهو مهيا ڪرڻ جو پابند هوندو آهي، جڏهن iterator طريقي کي سڏيو ويندو آهي، هڪ Iterator جيڪو انهي اعتراض جي مواد تي ٻيهر ڪندو. مٿي ڏنل ڪوڊ، مثال طور، هڪ بائيٽ ڪوڊ هوندو ڪجهه هن جهڙو (IntelliJ Idea ۾ توهان ڪري سگهو ٿا "View" -> "Show bytecode" :
هر هڪ لوپ لاءِ ۽ لاءِ: هڪ ڪهاڻي انهي بابت ڪيئن مون ٻيهر بيان ڪيو، بار بار ڪيو، پر ٻيهر نه ڪيو - 5
جئين توهان ڏسي سگهو ٿا، هڪ آئٽرٽر اصل ۾ استعمال ٿيندو آهي. جيڪڏهن اهو هر لوپ لاءِ نه هجي ها ته اسان کي ڪجهه لکڻو پوندو:
List<String> names = Arrays.asList("John", "Sara", "Jack");
for (Iterator i = names.iterator(); /* continue if */ i.hasNext(); /* skip increment */) {
	String name = (String) i.next();
	System.out.println("Name = " + name);
}

ورجائيندڙ

جيئن اسان مٿي ڏٺو، Iterable انٽرفيس چوي ٿو ته ڪجهه اعتراض جي مثالن لاء، توهان هڪ آئٽرٽر حاصل ڪري سگهو ٿا جنهن سان توهان مواد تي ٻيهر ڪري سگهو ٿا. ٻيهر، اهو چئي سگهجي ٿو SOLID کان اڪيلو ذميواري اصول . ڊيٽا جي جوڙجڪ پاڻ کي ٽرورسل کي هلائڻ نه گهرجي، پر اهو هڪ مهيا ڪري سگهي ٿو جيڪو گهرجي. Iterator جو بنيادي عمل اهو آهي ته اهو عام طور تي هڪ اندروني طبقي جي طور تي قرار ڏنو ويو آهي جيڪو ٻاهرئين طبقي جي مواد تائين رسائي حاصل ڪري ٿو ۽ ٻاهرين طبقي ۾ شامل گهربل عنصر مهيا ڪري ٿو. هتي ڪلاس مان هڪ مثال آهي ArrayListته ڪيئن هڪ آئٽرٽر هڪ عنصر واپس ڪري ٿو:
public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
}
جيئن اسان ڏسي سگهون ٿا، هڪ آئٽرٽر جي مدد سان ArrayList.thisٻاهرئين طبقي ۽ ان جي متغير تائين پهچندو آهي elementData، ۽ پوء اتان هڪ عنصر واپس آڻيندو آهي. تنهن ڪري، هڪ آئٽرٽر حاصل ڪرڻ بلڪل آسان آهي:
List<String> names = Arrays.asList("John", "Sara", "Jack");
Iterator<String> iterator = names.iterator();
ان جو ڪم ان حقيقت تي اچي ٿو ته اسان چيڪ ڪري سگھون ٿا ته ڇا عناصر آهن اڳتي ( hasNext method )، حاصل ڪريو ايندڙ عنصر ( next method ) ۽ هٽائڻ جو طريقو ، جيڪو آخري عنصر کي هٽائي ٿو ايندڙ ذريعي حاصل ڪيو . هٽائڻ جو طريقو اختياري آهي ۽ لاڳو ٿيڻ جي ضمانت نه آهي. حقيقت ۾، جيئن جاوا ترقي ڪري ٿو، انٽرفيس پڻ ترقي ڪن ٿا. تنهن ڪري، جاوا 8 ۾ پڻ هڪ طريقو هو forEachRemaining، جيڪو توهان کي ڪجهه عمل ڪرڻ جي اجازت ڏئي ٿو باقي عناصر تي عمل ڪندڙ طرفان دورو نه ڪيو ويو. ڇا هڪ iterator ۽ گڏ ڪرڻ جي باري ۾ دلچسپ آهي؟ مثال طور، اتي هڪ ڪلاس آهي AbstractList. هي هڪ خلاصو طبقو آهي جيڪو والدين آهي ArrayList۽ LinkedList. ۽ اهو اسان لاءِ دلچسپ آهي ڇاڪاڻ ته اهڙي فيلڊ جي ڪري modCount . هر هڪ فهرست جي مواد کي تبديل ڪري ٿو. پوءِ اهو اسان لاءِ ڇا آهي؟ ۽ حقيقت اها آهي ته آئٽرٽر انهي ڳالهه کي يقيني بڻائي ٿو ته آپريشن دوران اهو مجموعو جنهن تي ان کي بار بار ڪيو ويو آهي تبديل نٿو ڪري. جئين توهان سمجھو ٿا، فهرستن لاء آئٽرٽر جو نفاذ ساڳئي جڳهه تي واقع آهي modcount ، يعني، ڪلاس ۾ AbstractList. اچو ته هڪ سادي مثال ڏسو:
List<String> names = Arrays.asList("John", "Sara", "Jack");
names = new ArrayList(names);
Iterator<String> iterator = names.iterator();
names.add("modcount++");
System.out.println(iterator.next());
هتي پهرين دلچسپ شيء آهي، جيتوڻيڪ موضوع تي نه. اصل ۾ Arrays.asListپنهنجي خاص هڪ ArrayList( java.util.Arrays.ArrayList ) واپسي. اهو شامل ڪرڻ جي طريقن تي عمل نٿو ڪري، تنهنڪري اهو ناقابل قبول آهي. اهو JavaDoc ۾ لکيل آهي: fixed-size . پر حقيقت ۾، اهو مقرر ٿيل سائيز کان وڌيڪ آهي . اهو پڻ ناقابل بدلو آهي ، اهو آهي، ناقابل تبديلي؛ هٽائڻ به ان تي ڪم نه ڪندو. اسان کي به غلطي ملندي، ڇو ته... آئيٽرٽر ٺاهيندي، اسان ان ۾ modcount ياد ڪيو . ان کان پوء اسان "ٻاهرين" جي مجموعي جي حالت کي تبديل ڪيو (يعني، آئٽرٽر جي ذريعي نه) ۽ ايٽرٽر طريقي کي عمل ڪيو. تنهن ڪري، اسان کي غلطي ملي ٿي: java.util.ConcurrentModificationException . ان کان بچڻ لاءِ، تبديليءَ جي عمل دوران تبديلي پاڻ کي اٽيٽرٽر جي ذريعي ڪرڻ گھرجي، ۽ نه ته جمع تائين رسائي جي ذريعي:
List<String> names = Arrays.asList("John", "Sara", "Jack");
names = new ArrayList(names);
Iterator<String> iterator = names.iterator();
iterator.next();
iterator.remove();
System.out.println(iterator.next());
جيئن توهان سمجھو ٿا، جيڪڏهن iterator.remove()توهان ان کان اڳ نه ڪيو iterator.next()، پوء ڇو ته. iterator ڪنهن به عنصر ڏانهن اشارو نٿو ڪري، پوء اسان کي هڪ غلطي ملندي. مثال ۾، آئٽرٽر ڏانهن ويندا جان عنصر ، ان کي هٽايو، ۽ پوء حاصل ڪريو سارا عنصر . ۽ ھتي سڀ ڪجھ ٺيڪ ھوندو، پر بدقسمتيءَ سان، وري اتي ”نقصان“ آھن) java.util.ConcurrentModificationException تڏھن ٿيندو جڏھن hasNext()اھو سچو موٽندو . اهو آهي، جيڪڏهن توهان پاڻ کي گڏ ڪرڻ جي ذريعي آخري عنصر کي حذف ڪيو، ٻيهر نه ٿيندو. وڌيڪ تفصيلن لاءِ، اهو بهتر آهي ته رپورٽ ڏسو جاوا پزل بابت ” #ITsubbotnik سيڪشن JAVA: Java puzzles “. اسان اهڙي تفصيلي ڳالهه ٻولهه شروع ڪئي سادو سبب لاءِ ته بلڪل ساڳي نونسون لاڳو ٿينديون جڏهن for each loop... اسان جو پسنديده آئٽرٽر هود هيٺ استعمال ٿيندو آهي. ۽ اهي سڀ nuances اتي به لاڳو. صرف هڪ شيء آهي، اسان کي ايٽرٽر تائين رسائي نه هوندي، ۽ اسان عنصر کي محفوظ طور تي هٽائڻ جي قابل نه هوندا. رستي جي ذريعي، جيئن توهان سمجهي رهيا آهيو، رياست کي ياد ڪيو ويندو آهي ان وقت جڏهن ٻيهر ٺاهي وئي آهي. ۽ محفوظ حذف صرف ڪم ڪري ٿو جتي ان کي سڏيو ويندو آهي. اهو آهي، هي اختيار ڪم نه ڪندو:
Iterator<String> iterator1 = names.iterator();
Iterator<String> iterator2 = names.iterator();
iterator1.next();
iterator1.remove();
System.out.println(iterator2.next());
ڇاڪاڻ ته iterator2 لاءِ iterator1 ذريعي حذف ڪرڻ ”بيروني“ هو، يعني اهو ڪنهن ٻاهران ڪيو ويو هو ۽ هو ان بابت ڪجهه به نٿو ڄاڻي. Iterators جي موضوع تي، مان پڻ اهو نوٽ ڪرڻ چاهيندس. ھڪڙو خاص، وڌايو ويو آھي خاص طور تي انٽرفيس لاڳو ڪرڻ لاء List. ۽ انھن کيس نالو ڏنو ListIterator. اهو توهان کي نه رڳو اڳتي وڌڻ جي اجازت ڏئي ٿو، پر پوئتي پڻ، ۽ پڻ توهان کي پوئين عنصر جي انڊيڪس ۽ ايندڙ هڪ کي ڳولڻ جي اجازت ڏئي ٿو. اضافي طور تي، اهو توهان کي موجوده عنصر کي تبديل ڪرڻ يا موجوده آئٽرٽر پوزيشن ۽ ايندڙ هڪ جي وچ ۾ پوزيشن تي هڪ نئون داخل ڪرڻ جي اجازت ڏئي ٿو. جيئن توهان اندازو لڳايو، ListIteratorان کي ائين ڪرڻ جي اجازت آهي ڇاڪاڻ ته Listانڊيڪس ذريعي رسائي لاڳو ڪئي وئي آهي.
هر هڪ لوپ لاءِ ۽ لاءِ: هڪ ڪهاڻي جو مون ڪيئن ٻيهر بيان ڪيو، بار بار ڪيو، پر ٻيهر نه ڪيو - 6

جاوا 8 ۽ ورجائي

جاوا 8 جي ڇڏڻ ڪيترن ئي لاء زندگي آسان بڻائي ڇڏيو آهي. اسان شين جي مواد تي تڪرار کي به نظرانداز نه ڪيو. اهو سمجهڻ لاءِ ته اهو ڪيئن ڪم ڪري ٿو، توهان کي هن بابت ڪجهه چوڻ گهرجن. جاوا 8 متعارف ڪرايو java.util.function.Consumer ڪلاس . هتي هڪ مثال آهي:
Consumer consumer = new Consumer() {
	@Override
	public void accept(Object o) {
		System.out.println(o);
	}
};
صارفين هڪ فنڪشنل انٽرفيس آهي، جنهن جو مطلب آهي ته انٽرفيس جي اندر صرف 1 غير لاڳو ٿيل خلاصو طريقو آهي جنهن کي لازمي لاڳو ڪرڻ جي ضرورت آهي انهن طبقن ۾ جيڪي هن انٽرفيس جي عملن کي بيان ڪن ٿا. هي توهان کي اهڙي جادوگر شيءِ کي استعمال ڪرڻ جي اجازت ڏئي ٿو جيئن لامبدا. هي مضمون ان بابت نه آهي، پر اسان کي سمجهڻ جي ضرورت آهي ته اسان ان کي ڇو استعمال ڪري سگهون ٿا. تنهن ڪري، lambdas استعمال ڪندي، مٿين صارف کي هن طرح ٻيهر لکي سگهجي ٿو: Consumer consumer = (obj) -> System.out.println(obj); هن جو مطلب آهي ته جاوا ڏسي ٿو ته obj نالي ڪا شيءِ ان پٽ ڏانهن منتقل ڪئي ويندي، ۽ پوءِ اظهار -> هن اعتراض لاءِ عمل ڪيو ويندو. ورجائي لاء، اسان هاڻي ڪري سگهون ٿا:
List<String> names = Arrays.asList("John", "Sara", "Jack");
Consumer consumer = (obj) -> System.out.println(obj);
names.forEach(consumer);
جيڪڏهن توهان طريقي سان وڃو forEach، توهان ڏسندا ته هر شيء بلڪل سادي آهي. هتي اسان جي پسنديده هڪ آهي for-each loop:
default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
}
اهو پڻ ممڪن آهي ته خوبصورتي سان هڪ عنصر کي هٽائيندڙ استعمال ڪندي، مثال طور:
List<String> names = Arrays.asList("John", "Sara", "Jack");
names = new ArrayList(names);
Predicate predicate = (obj) -> obj.equals("John");
names.removeIf(predicate);
انهي صورت ۾، removeIf طريقو ان پٽ طور وٺندو آهي هڪ صارف نه ، پر هڪ Predicate . اهو بولين واپسي ٿو . انهي صورت ۾، جيڪڏهن اڳڪٿي چوي ٿو " سچو "، پوء عنصر کي هٽايو ويندو. اها دلچسپ آهي ته هتي سڀ ڪجهه واضح ناهي)) خير، توهان ڇا چاهيو ٿا؟ ڪانفرنس ۾ پزل ٺاهڻ لاءِ ماڻهن کي جاءِ ڏني وڃي. مثال طور، اچو ته هر شي کي حذف ڪرڻ لاءِ هيٺ ڏنل ڪوڊ وٺون جيڪو ٻيهر ڪرڻ وارو ڪجهه ورجائي کان پوءِ پهچي سگهي ٿو:
List<String> names = Arrays.asList("John", "Sara", "Jack");
names = new ArrayList(names);
Iterator<String> iterator = names.iterator();
iterator.next(); // Курсор на John
while (iterator.hasNext()) {
    iterator.next(); // Следующий элемент
    iterator.remove(); // Удалor его
}
System.out.println(names);
ٺيڪ آهي، هتي سڀ ڪجهه ڪم ڪري ٿو. پر اسان کي ياد آهي ته جاوا 8 آخرڪار. تنهن ڪري، اچو ته ڪوڊ کي آسان ڪرڻ جي ڪوشش ڪريو:
List<String> names = Arrays.asList("John", "Sara", "Jack");
names = new ArrayList(names);
Iterator<String> iterator = names.iterator();
iterator.next(); // Курсор на John
iterator.forEachRemaining(obj -> iterator.remove());
System.out.println(names);
ڇا اهو واقعي وڌيڪ خوبصورت ٿي ويو آهي؟ بهرحال، اتي هڪ java.lang.IllegalStateException هوندو . ۽ سبب آهي ... جاوا ۾ هڪ بگ. اهو ظاهر ٿئي ٿو ته اهو مقرر ٿيل آهي، پر JDK 9 ۾. هتي OpenJDK ۾ ڪم جي هڪ لنڪ آهي: Iterator.forEachRemaining vs. Iterator.remove . قدرتي طور تي، اهو اڳ ۾ ئي بحث ڪيو ويو آهي: ڇو iterator.forEachRemaining صارف ليمبڊا ۾ عنصر کي ختم نٿو ڪري؟ خير، ٻيو طريقو سڌو سنئون اسٽريم API ذريعي آهي:
List<String> names = new ArrayList(Arrays.asList("John", "Sara", "Jack"));
Stream<String> stream = names.stream();
stream.forEach(obj -> System.out.println(obj));

نتيجا

جيئن اسان مٿين سڀني مواد مان ڏٺو، هڪ لوپ for-each loopصرف "نحوي شوگر" آهي هڪ آئٽرٽر جي چوٽي تي. بهرحال، اهو هاڻي ڪيترن ئي هنڌن تي استعمال ڪيو ويندو آهي. ان کان سواء، ڪنهن به پيداوار احتياط سان استعمال ڪيو وڃي. مثال طور، هڪ بي ضرر هڪ forEachRemainingاڻ وڻندڙ ​​تعجب لڪائي سگهي ٿو. ۽ اهو هڪ ڀيرو ٻيهر ثابت ٿئي ٿو ته يونٽ ٽيسٽ جي ضرورت آهي. هڪ سٺو امتحان توهان جي ڪوڊ ۾ اهڙي استعمال جي صورت جي سڃاڻپ ڪري سگهي ٿي. توهان موضوع تي ڇا ڏسي / پڙهي سگهو ٿا: #وياچسلاو
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION