CodeGym /Java Blog /यादृच्छिक /ArrayList मधून घटक हटवत आहे
John Squirrels
पातळी 41
San Francisco

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 वर अॅरे घटक सेट केल्याने "छिद्र" निघते. आम्ही अॅरेमधील स्थान काढले नाही, फक्त त्यातील सामग्री. कल्पना करा की आमच्याकडे ५० मांजरी असतील आणि त्यांपैकी १७ अशा प्रकारे काढल्या तर काय होईल. आमच्याकडे 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, परंतु इतर प्रकारांसह नाही. दुसऱ्या शब्दांत सांगायचे तर, जर प्रोग्राममध्ये आणखी १०० क्लासेस आहेत जे आपल्याला अॅरेसह वापरायचे आहेत, तर आपल्याला त्या प्रत्येकामध्ये समान तर्कासह समान पद्धत लिहावी लागेल. ही एक संपूर्ण आपत्ती आहे -_- पण 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());
}
आउटपुट: [मांजर{नाम='थॉमस'}, मांजर{नाम='बेहेमोथ'}, मांजर{नाम='लिओनेल मेस्सी'}, मांजर{नाम='फ्लफी'}] [मांजर{नाम='थॉमस'}, मांजर{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.util.ConcurrentModificationException थ्रेडमधील अपवाद. java:831) Cat.main(Cat.java:25) येथे काही प्रकारची त्रुटी आहे आणि ती का आली हे स्पष्ट नाही. या प्रक्रियेमध्ये अनेक बारकावे समाविष्ट आहेत ज्यांना संबोधित करणे आवश्यक आहे. तुम्हाला लक्षात ठेवण्याची आवश्यकता असलेला सामान्य नियम येथे आहे: तुम्ही एकाच वेळी संग्रहावर पुनरावृत्ती करू शकत नाही आणि त्याचे घटक बदलू शकत नाही. आणि आमचा अर्थ कोणत्याही प्रकारचा बदल, केवळ काढून टाकणे नव्हे. जर तुम्ही मांजर काढण्याच्या जागी नवीन मांजरी घालण्याच्या प्रयत्नात असाल, तर परिणाम समान असेल:

for (Cat cat: cats) {

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

System.out.println(cats);
java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859) येथे java.util.ArrayList$Itr.next(ArrayList.java:831) येथे "मुख्य" थ्रेडमधील java.util.ConcurrentModificationException. 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>). मुख्य गोष्ट अशी आहे की पुनरावृत्ती करणारा आमचे मूळ कार्य सहजपणे हाताळतो. उदाहरणार्थ, "लिओनेल मेस्सी" नावाची मांजर काढा:

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);
आऊटपुट: [मांजर{नाम='थॉमस'}, मांजर{नाम='बेहेमोथ'}, मांजर{नाम='फ्लफी'}] तुमच्या लक्षात आले असेल की आम्ही इटरेटरच्या पद्धतीमध्ये अनुक्रमणिका किंवा नाव निर्दिष्ट केलेले remove()नाही ! इटरेटर दिसण्यापेक्षा हुशार आहे: remove()इटरेटरद्वारे परत केलेला शेवटचा घटक काढून टाकतो. जसे तुम्ही बघू शकता, आम्हाला जे करायचे होते तेच केले :) तत्वतः, मधून घटक काढून टाकण्याबद्दल तुम्हाला हे सर्व माहित असणे आवश्यक आहे ArrayList. बरं, जवळजवळ सर्व काही. पुढील धड्यात, आपण या वर्गात पाहू, आणि विविध पद्धतीच्या कॉल्स दरम्यान तेथे काय होते ते पाहू :) तोपर्यंत!
टिप्पण्या
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION