CodeGym /جاوا بلاگ /Random-UR /ArrayList سے ایک عنصر کو حذف کرنا
John Squirrels
سطح
San Francisco

ArrayList سے ایک عنصر کو حذف کرنا

گروپ میں شائع ہوا۔
ہائے! پچھلے سبق میں، ہم نے ArrayListکلاس سے واقفیت حاصل کی، اور اس کلاس کے ساتھ سب سے عام آپریشنز کرنے کا طریقہ سیکھا۔ ArrayListاس کے علاوہ، ہم نے ایک اور ایک عام صف کے درمیان کئی فرقوں کی نشاندہی کی ۔ لیکن ہم نے ایک موضوع کو اسکرٹ کیا، یعنی، سے عناصر کو کیسے حذف کریںArrayList ۔ اب ہم اس پر بات کریں گے۔ ArrayList سے کسی عنصر کو حذف کرنا - 1ہم پہلے ہی بتا چکے ہیں کہ ایک عام صف سے عناصر کو حذف کرنا زیادہ آسان نہیں ہے۔ چونکہ ہم خود عنصر کو حذف نہیں کرسکتے ہیں، اس لیے ہم صرف اس کی قدر کو "صفر آؤٹ" (نال پر سیٹ) کر سکتے ہیں:
public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

       Cat[] cats = new Cat[3];
       cats[0] = new Cat("Thomas");
       cats[1] = new Cat("Behemoth");
       cats[2] = new Cat("Lionel Messi");

       cats[1] = null;

       System.out.println(Arrays.toString(cats));
   }


@Override
   public String toString() {
       return "Cat{" +
               "name='" + name + '\'' +
               '}';
   }
}
آؤٹ پٹ: [Cat{name='Thomas'}, null, Cat{name='Lionel Messi'}] لیکن ایک سرنی عنصر کو null کرنے سے "ہول" نکل جاتا ہے۔ ہم نے صف میں پوزیشن کو نہیں ہٹایا ہے، صرف اس کے مواد کو۔ تصور کریں کہ کیا ہوگا اگر ہمارے پاس 50 بلیوں کی ایک صف ہوتی اور ان میں سے 17 کو اس طرح ہٹا دیا جاتا۔ ہمارے پاس 17 سوراخوں والی ایک صف ہوگی۔ بس ان پر نظر رکھنے کی کوشش کریں! خالی خلیوں کی تعداد کو یاد رکھنے کی توقع کرنا غیر حقیقی ہے جہاں آپ نئی قدریں لکھ سکتے ہیں۔ اگر آپ ایک غلطی کرتے ہیں، تو آپ ایک آبجیکٹ کا حوالہ اوور رائٹ کر دیں گے جو آپ چاہتے ہیں۔ بلاشبہ، تھوڑا اور احتیاط سے ایسا کرنے کا ایک طریقہ ہے: کسی عنصر کو ہٹانے کے بعد، عناصر کو سرنی کے سامنے لے جائیں تاکہ آخر میں "سوراخ" ڈالیں:
public static void main(String[] args) {

   Cat[] cats = new Cat[4];
   cats[0] = new Cat("Thomas");
   cats[1] = new Cat("Behemoth");
   cats[2] = new Cat("Lionel Messi");
   cats[2] = new Cat("Fluffy");

   cats[1] = null;

   for (int i = 2; i < cats.length-1; i++) {
       cats [i-1] = cats [i];// Move the elements to the front of the array, so the empty position is at the end
   }

   System.out.println(Arrays.toString(cats));
}
آؤٹ پٹ: [Cat{name='Thomas'}, Cat{name='Fluffy'}, Cat{name='Fluffy'}, null] یہ بہتر معلوم ہوتا ہے، لیکن اسے شاید ہی ایک مضبوط حل کہا جا سکے۔ اگر اس حقیقت کے علاوہ کوئی اور وجہ نہیں ہے کہ جب ہم کسی سرنی سے کسی عنصر کو حذف کرتے ہیں تو ہمیں ہر بار یہ کوڈ لکھنا پڑتا ہے! یہ ایک برا آپشن ہے۔ ہم دوسرے طریقے سے جا سکتے ہیں اور ایک الگ طریقہ بنا سکتے ہیں:
public void deleteCat(Cat[] cats, int indexToDelete) {
   //...delete the cat corresponding to the index and move the elements
}
لیکن یہ بھی بہت کم فائدہ مند ہے: یہ طریقہ صرف اشیاء کے ساتھ کام کر سکتا ہے Cat، لیکن دوسری اقسام کے ساتھ نہیں۔ دوسرے لفظوں میں، اگر کسی پروگرام میں مزید 100 کلاسیں ہیں جنہیں ہم arrays کے ساتھ استعمال کرنا چاہتے ہیں، تو ہمیں ان میں سے ہر ایک میں بالکل ایک ہی منطق کے ساتھ ایک ہی طریقہ لکھنا ہوگا۔ یہ ایک مکمل آفت ہے -_- لیکن ArrayListکلاس اس مسئلے کو حل کرتی ہے! یہ عناصر کو ہٹانے کے لیے ایک خاص طریقہ نافذ کرتا ہے:remove()
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);
   System.out.println(cats.toString());

   cats.remove(1);

   System.out.println(cats.toString());
}
ہم اپنے آبجیکٹ کے انڈیکس کو طریقہ میں منتقل کرتے ہیں، جو اسے حذف کر دیتا ہے (جیسے کسی صف میں)۔ طریقہ remove()کار میں دو خاص خصوصیات ہیں۔ سب سے پہلے، یہ "سوراخ" نہیں چھوڑتا ہے. یہ پہلے سے ہی عناصر کو منتقل کرنے کے لیے درکار منطق کو نافذ کرتا ہے جب کسی عنصر کو درمیان سے ہٹا دیا جاتا ہے، جسے ہم نے پہلے خود لکھا تھا۔ پچھلے کوڈ سے آؤٹ پٹ کو دیکھیں:
[Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Lionel Messi'}, Cat{name='Fluffy'}]

[Cat{name='Thomas'}, Cat{name='Lionel Messi'}, Cat{name='Fluffy'}]
ہم نے ایک بلی کو درمیان سے ہٹا دیا، اور باقی کو منتقل کر دیا گیا تاکہ کوئی خالی جگہ نہ ہو۔ دوسرا ، یہ اشیاء کو نہ صرف انڈیکس (ایک عام صف کی طرح) کے ذریعے حذف کر سکتا ہے، بلکہ حوالہ سے بھی :
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);
   System.out.println(cats.toString());

   cats.remove(lionel);

   System.out.println(cats.toString());
}
آؤٹ پٹ: [Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Lionel Messi'}, Cat{name='Fluffy'}] [Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Fluffy'}] یہ بہت آسان ہوسکتا ہے اگر آپ ہمیشہ مطلوبہ چیز کے انڈیکس پر نظر نہیں رکھنا چاہتے ہیں۔ ایسا لگتا ہے کہ ہم نے عام حذف کا پتہ لگا لیا ہے۔ اب آئیے اس صورتحال کا تصور کریں: ہم اپنی فہرست پر اعادہ کرنا چاہتے ہیں اور ایک مخصوص نام والی بلی کو ہٹانا چاہتے ہیں ۔ ایسا کرنے کے لیے، ہم ایک تیز forلوپ (جسے ہر ایک کے لیے لوپ بھی کہا جاتا ہے) استعمال کریں گے، جس سے ہمیں رشی کے اسباق میں متعارف کرایا گیا تھا:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   for (Cat cat: cats) {

       if (cat.name.equals("Behemoth")) {
           cats.remove(cat);
       }
   }

   System.out.println(cats);
}
کوڈ بالکل منطقی لگتا ہے۔ لیکن نتیجہ ایک بڑا تعجب کا باعث ہو سکتا ہے: java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859) پر java.util.ArrayList$Itr.next.(ArrayList. java:831) Cat.main(Cat.java:25) میں کسی قسم کی خرابی ہے، اور یہ واضح نہیں ہے کہ ایسا کیوں ہوا۔ اس عمل میں متعدد باریکیاں شامل ہیں جن پر توجہ دینا ضروری ہے۔ یہاں عام اصول ہے جو آپ کو یاد رکھنے کی ضرورت ہے: آپ بیک وقت کسی مجموعہ پر اعادہ نہیں کرسکتے اور اس کے عناصر کو تبدیل نہیں کرسکتے ہیں۔ اور ہمارا مطلب کسی بھی قسم کی تبدیلی ہے، نہ کہ محض ہٹانا۔ اگر آپ بلی ہٹانے کی جگہ نئی بلیاں ڈالنے کی کوشش کرتے ہیں، تو نتیجہ وہی ہوگا:
for (Cat cat: cats) {

   cats.add(new Cat("Salem Saberhagen"));
}

System.out.println(cats);
دھاگے "main" java.util.ConcurrentModificationException میں java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859) java.util.ArrayList$Itr.next(ArrayList.java پر Cat.831) Cat.java:25) ہم نے ایک آپریشن کو دوسرے میں تبدیل کیا، لیکن نتیجہ نہیں بدلا: ہمیں وہی ConcurrentModificationException ملتا ہے ۔ یہ عین اس وقت ہوتا ہے جب ہم فہرست کو تبدیل کرتے ہوئے اوپر والے اصول کو توڑنے کی کوشش کرتے ہیں۔ جاوا میں، ہمیں ایک خاص شے کی ضرورت ہوتی ہے جسے ایٹریٹر (Iteratorکلاس) کہا جاتا ہے تاکہ کسی مجموعہ پر تکرار کرتے وقت آئٹمز کو حذف کیا جا سکے۔ کلاسIteratorعناصر کی فہرست پر محفوظ طریقے سے تکرار کرنے کی ذمہ دار ہے۔ یہ بہت آسان ہے، کیونکہ اس کے صرف 3 طریقے ہیں:
  • hasNext()- صحیح یا غلط لوٹاتا ہے، اس پر منحصر ہے کہ آیا فہرست میں اگلی آئٹم ہے، یا ہم پہلے ہی آخری پر پہنچ چکے ہیں۔
  • next()- فہرست میں اگلی آئٹم واپس کرتا ہے۔
  • remove()- فہرست سے ایک آئٹم کو ہٹاتا ہے۔
جیسا کہ آپ دیکھ سکتے ہیں، تکرار کرنے والا ہماری ضروریات کے مطابق بنایا گیا ہے، اور ساتھ ہی اس میں کوئی پیچیدہ بات نہیں ہے۔ فرض کریں کہ ہم یہ دیکھنا چاہتے ہیں کہ آیا ہماری فہرست میں کوئی اگلا عنصر موجود ہے، اور اگر وہاں ہے تو اسے ڈسپلے کریں:
Iterator<Cat> catIterator = cats.iterator();// Create an iterator
while(catIterator.hasNext()) {// As long as there are elements in the list

   Cat nextCat = catIterator.next();// Get the next element
   System.out.println(nextCat);// Display it
}
آؤٹ پٹ: Cat{name='Thomas'} Cat{name='Behemoth'} Cat{name='Lionel Messi'} Cat{name='Fluffy'} جیسا کہ آپ دیکھ سکتے ہیں، اس نے پہلے سے ہی ایک بنانے کے لیے ایک ArrayListخاص طریقہ نافذ کر دیا ہے۔ تکرار کرنے والا : iterator(). مزید برآں، نوٹ کریں کہ جب ہم ایک ایٹریٹر بناتے ہیں، تو ہم اشیاء کی کلاس بتاتے ہیں جس کے ساتھ یہ کام کرے گا <Cat>۔ سب سے اہم بات یہ ہے کہ ایک تکرار کرنے والا ہمارے اصل کام کو آسانی سے سنبھال لیتا ہے۔ مثال کے طور پر، "Lionel Messi" نامی بلی کو ہٹا دیں:
Iterator<Cat> catIterator = cats.iterator();// Create an iterator
while(catIterator.hasNext()) {// As long as there are elements in the list

   Cat nextCat = catIterator.next();// Get the next element
   if (nextCat.name.equals("Lionel Messi")) {
       catIterator.remove();// Delete the cat with the specified name
   }
}

System.out.println(cats);
آؤٹ پٹ: [Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Fluffy'}]remove() آپ نے محسوس کیا ہو گا کہ ہم نے دوبارہ کرنے والے کے طریقہ کار میں انڈیکس یا نام کی وضاحت نہیں کی ہے۔ ! تکرار کرنے والا اس سے زیادہ ہوشیار ہے جو ظاہر ہوسکتا ہے: remove()تکرار کرنے والے کے ذریعہ واپس کردہ آخری عنصر کو ہٹاتا ہے۔ جیسا کہ آپ دیکھ سکتے ہیں، اس نے وہی کیا جو ہم کرنا چاہتے تھے :) اصولی طور پر، یہ وہ سب کچھ ہے جو آپ کو ایک سے عناصر کو ہٹانے کے بارے میں جاننے کی ضرورت ہے ArrayList۔ ٹھیک ہے، تقریبا سب کچھ. اگلے سبق میں، ہم اس کلاس کے اندر دیکھیں گے، اور دیکھیں گے کہ مختلف میتھڈ کالز کے دوران وہاں کیا ہوتا ہے :) تب تک!
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION