JavaRush /Блоги Java /Random-TG /Хориҷ кардани элемент аз ArrayList дар Java

Хориҷ кардани элемент аз ArrayList дар Java

Дар гурӯҳ нашр шудааст
Салом! Дар лексияи охир мо бо синфи 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("Hippopotamus");
       cats[2] = new Cat("Philip Markovich");

       cats[1] = null;

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


@Override
   public String toString() {
       return "Cat{" +
               "name='" + name + '\'' +
               '}';
   }
}
Хулоса:

[Cat{name='Томас'}, null, Cat{name='Фorпп Маркович'}]
Аммо ҳангоми аз нав танзим кардан, дар массив "сӯрох" боқӣ мемонад. Мо ячейкаро нест мекунем, балки танҳо мундариҷаи онро нест мекунем. Тасаввур кунед, ки агар мо массиви 50 гурба дошта бошем, ки 17-тои онҳоро бо ин роҳ нест карда бошем, чӣ мешавад. Мо массиви дорои 17 сӯрохиро дорем ва ба онҳо нигоҳ мекунем! Дар хотир нигоҳ доштани шумораи ҳуҷайраҳои холӣ, ки дар он шумо метавонед арзишҳои нав нависед, ғайривоқеист. Як маротиба хато кунед ва шумо чашмакро бо истинодҳои дилхоҳ ба an object аз нав менависед. Албатта, имкон дорад, ки ин корро каме бодиққат анҷом диҳед: пас аз нест кардан, элементҳои массивро ба аввал интиқол диҳед, то "сӯрох" дар охири он бошад:
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));
}
Хулоса:

[Cat{name='Томас'}, Cat{name='Фorпп Маркович'}, Cat{name='Пушок'}, null]
Ҳоло ба назар чунин менамояд, ки ин беҳтар аст, аммо инро роҳи ҳалли устувор номидан душвор аст. Ҳадди ақал, зеро мо бояд ҳар дафъае, ки элементро аз массив хориҷ кунем, ин codeро дастӣ нависем! Варианти бад. Шумо метавонед бо роҳи дигар равед ва усули алоҳида эҷод кунед:
public void deleteCat(Cat[] cats, int indexToDelete) {
   //...remove the cat by index and shift the elements
}
Аммо ин низ чандон фоиданок нест: ин усул метавонад танҳо бо an objectҳо кор кунад Cat, аммо бо дигарон кор карда наметавонад. Яъне, агар дар барномае, ки мо мехоҳем массивҳоро истифода кунем, боз 100 синфи дигар мавҷуд бошад, мо бояд дар ҳар кадоми онҳо ҳамон усулро бо мантиқи якхела нависем. Ин як нокомии комил аст -_- Аммо дар синфи ArrayList ин масъала бомуваффақият ҳал карда мешавад! Он усули махсусро барои нест кардани элементҳо амалӣ мекунад - 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());
}
Мо индекси an objectи худро ба метод гузаштем ва он нест карда шуд (мисли дар массив). Усул remove()ду хусусият дорад. Аввалан , он "сӯрохӣ" намегузорад. Он аллакай мантиқи иваз кардани элементҳоро ҳангоми хориҷ кардани элемент аз мобайн амалӣ мекунад, ки мо қаблан онро дастӣ навишта будем. Ба баромади рамзи қаблӣ дар консол нигаред:

[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Фorпп Маркович'}, Cat{name='Пушок'}]
[Cat{name='Томас'}, Cat{name='Фorпп Маркович'}, Cat{name='Пушок'}]
Як гурбаро аз мобайн бардоштему дигаронро ба гирду атроф равон кардем, то холӣ набошад. Дуюм , он метавонад an objectро на танҳо аз рӯи индекс (ба мисли массиви муқаррарӣ), балки инчунин бо истинод ба an object нест кунад :
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());
}
Хулоса:

[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Фorпп Маркович'}, Cat{name='Пушок'}]
[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Пушок'}]
Ин метавонад хеле қулай бошад, агар шумо нахоҳед, ки ҳамеша индекси an objectи дилхоҳро дар сари худ нигоҳ доред. Чунин ба назар мерасад, ки мо ҳазфи муқаррариро ҳал кардаем. Акнун биёед ин вазъиятро тасаввур кунем: мо мехоҳем тавассути рӯйхати унсурҳои худ такрор кунем ва гурбаро бо номи муайян хориҷ кунем. Барои ин мо оператори махсуси ҳалқаро истифода мебарем for- for each. Шумо метавонед дар ин лексия бештар дар бораи он маълумот гиред .
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);
}
Чунин ба назар мерасад, ки code комилан мантиқӣ аст. Бо вуҷуди ин, натиҷа метавонад шуморо ба ҳайрат орад:

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)
Як навъ хато, ва маълум нест, ки чаро он ногаҳон пайдо шуд. Дар ин раванд як қатор нозукиҳо мавҷуданд, ки бояд онҳоро ҳал кард. Қоидаи умумие, ки шумо бояд дар хотир доред: Шумо наметавонед дар як вақт коллексияро такрор кунед ва унсурҳои онро тағир диҳед. Бале, бале, маҳз тағирот, на танҳо нест кардан. Агар шумо дар codeи мо кӯшиш кунед, ки нест кардани гурбаҳоро бо ворид кардани гурбаҳои нав иваз кунед, натиҷа ҳамон хоҳад буд:
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)
Мо як амалиётро ба дигараш иваз кардем, аммо натиҷа тағир наёфт: ҳамон хатогӣ ConcurrentModificationException. Он маҳз вақте рух медиҳад, ки мо кӯшиш мекунем қоидаро вайрон кунем ва рӯйхатро ҳангоми такрори он тағир диҳем. Дар Java, барои нест кардани элементҳо ҳангоми такрорӣ, шумо бояд an objectи махсусро истифода баред - итератор (класс Iterator). Синф Iteratorбарои бехатар гузаштан аз рӯйхати элементҳо масъул аст. Ин хеле содда аст, зеро он танҳо 3 усул дорад:
  • hasNext()- бар мегардонад trueё falseвобаста ба мавҷудияти унсури навбатӣ дар рӯйхат ё мо аллакай ба охиринаш расидаем.
  • 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 next element
   System.out.println(nextCat);// print it to the console
}
Хулоса:

Cat{name='Томас'}
Cat{name='Бегемот'}
Cat{name='Фorпп Маркович'}
Cat{name='Пушок'}
Тавре ки шумо мебинед, синф ArrayListаллакай усули махсуси эҷоди итератор - iterator(). Инчунин, қайд кунед, ки ҳангоми сохтани итератор мо синфи an objectҳоеро, ки бо онҳо кор хоҳад кард, муайян мекунем ( <Cat>). Дар ниҳоят, мо метавонем бо истифода аз итератор мушкилоти аслии худро ҳал кунем. Масалан, биёед гурбаеро бо номи "Фorп Маркович" нест кунем:
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);
Хулоса:

[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Пушок'}]
Шумо шояд пай бурда бошед, ки мо дар усули итератор на индекси элемент ё номи тағирёбандаи истинодро муайян накардаем remove()! Итератор донотар аз он аст, ки ба назар мерасад: усул remove()унсури охирини аз ҷониби итератор баргардонидашударо нест мекунад. Тавре ки шумо мебинед, он маҳз ҳамон тавре ки лозим буд, кор кард :) Ин аслан ҳама чизест, ки шумо дар бораи хориҷ кардани элементҳо аз ArrayList. Аниқтараш - қариб ҳама чиз. Дар лексияи навбатӣ мо ба «даруни» ин синф назар хоҳем кард ва бубинем, ки дар он ҷо ҳангоми амалиёт чӣ ҳодиса рӯй медиҳад :) То дидан!
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION