JavaRush /Java Blogu /Random-AZ /Java-da ArrayList-dən elementin çıxarılması

Java-da ArrayList-dən elementin çıxarılması

Qrupda dərc edilmişdir
Salam! Keçən mühazirədə biz ArrayList sinfi ilə tanış olduq , həmçinin onunla ən çox yayılmış əməliyyatları yerinə yetirməyi öyrəndik. Bundan əlavə, biz ArrayList ilə adi massiv arasında bir neçə fərqi vurğuladıq. İndi ArrayList-dən elementin çıxarılmasına baxaq. Artıq dedik ki, adi massivdə elementləri silmək çox rahat deyil. ArrayList-dən elementin çıxarılması - 1Hüceyrənin özünü silə bilmədiyimiz üçün onun dəyərini yalnız “sıfırlaya” bilərik:
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("Hippopotamus");
       cats[2] = new Cat("Philip Markovich");

       cats[1] = null;

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


@Override
   public String toString() {
       return "Cat{" +
               "name='" + name + '\'' +
               '}';
   }
}
Nəticə:

[Cat{name='Томас'}, null, Cat{name='Фorпп Маркович'}]
Lakin sıfırlandıqda massivdə “deşik” qalır. Biz hüceyrəni deyil, yalnız onun məzmununu silirik. Təsəvvür edin, 17-ni bu şəkildə sildiyimiz 50 pişik massivimiz olsa nə baş verəcək. 17 deşikli bir massivimiz olacaq və onlara baxacağıq! Yeni dəyərlər yaza biləcəyiniz boş xanaların sayını əzbərdən xatırlamaq qeyri-realdır. Bir dəfə səhv edin və siz obyektə istədiyiniz istinad ilə xananın üzərinə yazacaqsınız. Əlbətdə ki, bunu bir az daha diqqətlə etmək imkanı var: sildikdən sonra massivin elementlərini başlanğıca köçürün ki, "çuxur" sonunda olsun:
public static void main(String[] args) {

   Cat[] cats = new Cat[4];
   cats[0] = new Cat("Thomas");
   cats[1] = new Cat("Hippopotamus");
   cats[2] = new Cat("Philip Markovich");
   cats[3] = new Cat("Fluff");

   cats[1] = null;

   for (int i = 2; i < cats.length-1; i++) {
       //move the elements to the beginning so that the empty cell is at the end
       cats[i-1] = cats[i];
       cats[i] = null;
   }

   System.out.println(Arrays.toString(cats));
}
Nəticə:

[Cat{name='Томас'}, Cat{name='Фorпп Маркович'}, Cat{name='Пушок'}, null]
İndi daha yaxşı görünür, amma bunu sabit bir həll adlandırmaq çətindir. Ən azı ona görə ki, hər dəfə massivdən elementi siləndə bu kodu əllə yazmalı olacağıq! Pis variant. Siz başqa yolla gedə və ayrı bir üsul yarada bilərsiniz:
public void deleteCat(Cat[] cats, int indexToDelete) {
   //...remove the cat by index and shift the elements
}
Ancaq bunun da az faydası var: bu üsul yalnız obyektlərlə işləyə bilər Cat, lakin başqaları ilə işləyə bilməz. Yəni massivlərdən istifadə etmək istədiyimiz proqramda daha 100 sinif varsa, onların hər birində tam eyni məntiqlə eyni metodu yazmalı olacağıq. Bu tam uğursuzluqdur -_- Amma ArrayList sinfində bu problem uğurla həll olunur! Elementləri çıxarmaq üçün xüsusi bir üsul tətbiq edir - remove():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);
   System.out.println(cats.toString());

   cats.remove(1);

   System.out.println(cats.toString());
}
Obyektimizin indeksini metoda ötürdük və o, silindi (massivdəki kimi). Metodun remove()iki xüsusiyyəti var. Birincisi , o, "deşiklər" buraxmır. O , əvvəllər əl ilə yazdığımız elementi ortadan çıxararkən elementlərin dəyişdirilməsi məntiqini artıq həyata keçirir . Konsolda əvvəlki kodun çıxışına baxın:

[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Фorпп Маркович'}, Cat{name='Пушок'}]
[Cat{name='Томас'}, Cat{name='Фorпп Маркович'}, Cat{name='Пушок'}]
Bir pişiyi ortadan çıxardıq, digərlərini isə yerindən oynatdıq ki, boşluq olmasın. İkincisi , o, obyekti təkcə indekslə deyil (adi massiv kimi), həm də obyektə istinadla silə bilər :
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);
   System.out.println(cats.toString());

   cats.remove(philipp);

   System.out.println(cats.toString());
}
Nəticə:

[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Фorпп Маркович'}, Cat{name='Пушок'}]
[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Пушок'}]
İstədiyiniz obyektin indeksini həmişə başınızda saxlamaq istəmirsinizsə, bu çox rahat ola bilər. Deyəsən, adi silinməni sıraladıq. İndi bu vəziyyəti təsəvvür edək: biz elementlər siyahımızı təkrarlamaq və müəyyən bir adı olan bir pişiyi silmək istəyirik. Bunun üçün xüsusi loop operatorundan istifadə edirik for- for each. Bu mühazirədə bu barədə daha çox məlumat əldə edə bilərsiniz .
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   for (Cat cat: cats) {

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

   System.out.println(cats);
}
Kod olduqca məntiqli görünür. Ancaq nəticə sizi təəccübləndirə bilər:

Exception in thread "main" java.util.ConcurrentModificationException
  at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
  at java.util.ArrayList$Itr.next(ArrayList.java:831)
  at Cat.main(Cat.java:25)
Bir növ səhv və birdən-birə niyə ortaya çıxdığı aydın deyil. Bu prosesdə həll edilməli olan bir sıra nüanslar var. Yadda saxlamağınız lazım olan ümumi qayda: Siz kolleksiyanı təkrarlaya və onun elementlərini eyni vaxtda dəyişə bilməzsiniz. Bəli, bəli, dəqiq bir dəyişiklik və yalnız silmə deyil. Əgər kodumuzda pişiklərin çıxarılmasını yenilərinin daxil edilməsi ilə əvəz etməyə cəhd etsəniz, nəticə eyni olacaq:
for (Cat cat: cats) {

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

System.out.println(cats);

Exception in thread "main" java.util.ConcurrentModificationException
  at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
  at java.util.ArrayList$Itr.next(ArrayList.java:831)
  at Cat.main(Cat.java:25)
Bir əməliyyatı digərinə dəyişdik, lakin nəticə dəyişmədi: eyni xəta ConcurrentModificationException. Bu, bir qaydanı pozmağa və onu təkrarlayarkən siyahını dəyişdirməyə çalışdığımız zaman baş verir. Java-da iterasiya zamanı elementləri silmək üçün xüsusi obyektdən - iteratordan (sinif) istifadə etməlisiniz Iterator. Sinif Iteratorelementlər siyahısından təhlükəsiz şəkildə keçməyə cavabdehdir. Bu olduqca sadədir, çünki onun yalnız 3 üsulu var:
  • hasNext()- trueya falsesiyahıda növbəti elementin olub-olmamasından, ya da sonuncuya çatmağımızdan asılı olaraq qaytarır.
  • next()- siyahının növbəti elementini qaytarır
  • remove()- siyahıdan elementi silir
Gördüyünüz kimi, iterator sözün əsl mənasında ehtiyaclarımıza "uyğunlaşdırılıb" və bunda mürəkkəb bir şey yoxdur. Məsələn, siyahımızda aşağıdakı elementin olub-olmadığını yoxlamaq istəyirik və əgər varsa, onu konsolda çap edin:
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 next element
   System.out.println(nextCat);// print it to the console
}
Nəticə:

Cat{name='Томас'}
Cat{name='Бегемот'}
Cat{name='Фorпп Маркович'}
Cat{name='Пушок'}
Gördüyünüz kimi, sinif ArrayListartıq iterator yaratmaq üçün xüsusi bir üsul tətbiq edir - iterator(). Həmçinin qeyd edək ki, iterator yaratarkən onun işləyəcəyi obyektlərin sinfini müəyyənləşdiririk ( <Cat>). Nəhayət, bir iteratordan istifadə edərək orijinal problemimizi asanlıqla həll edə bilərik. Məsələn, "Philip Markoviç" adlı bir pişiyi silək:
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 next element
   if (nextCat.name.equals("Philip Markovich")) {
       catIterator.remove();//delete the cat with the desired name
   }
}

System.out.println(cats);
Nəticə:

[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Пушок'}]
Siz iterator metodunda nə element indeksini, nə də istinad dəyişənin adını qeyd etmədiyimizi görmüsünüz remove()! İterator göründüyündən daha ağıllıdır: metod remove()iterator tərəfindən qaytarılmış sonuncu elementi silir. Gördüyünüz kimi, tam lazım olduğu kimi işlədi :) Əsasən elementləri silmək haqqında bilmək lazım olan hər şey budur ArrayList. Daha doğrusu - demək olar ki, hər şey. Növbəti mühazirədə biz bu sinfin “içinə” baxacağıq və əməliyyatlar zamanı orada nə baş verdiyini görəcəyik :) Görüşənədək!
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION