హాయ్! చివరి పాఠంలో, మేము తరగతితో పరిచయం పొందాము
సాధారణ శ్రేణి నుండి మూలకాలను తొలగించడం చాలా సౌకర్యవంతంగా లేదని మేము ఇప్పటికే పేర్కొన్నాము. మేము మూలకాన్ని తొలగించలేము కాబట్టి, మనం దాని విలువను "సున్నా అవుట్" (శూన్యానికి సెట్) మాత్రమే చేయగలము:
ArrayList
మరియు ఈ తరగతితో అత్యంత సాధారణ కార్యకలాపాలను ఎలా నిర్వహించాలో నేర్చుకున్నాము. అదనంగా, మేము ఒక ArrayList
మరియు సాధారణ శ్రేణి మధ్య అనేక తేడాలను ఎత్తి చూపాము. కానీ మేము ఒక అంశాన్ని దాటవేశాము, అవి ఒక నుండి ఎలిమెంట్లను ఎలా తొలగించాలిArrayList
. మేము ఇప్పుడు దాని గురించి చర్చిస్తాము. 
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'}] కానీ శ్రేణి మూలకాన్ని శూన్యంగా అమర్చడం వలన "రంధ్రం" ఏర్పడుతుంది. మేము శ్రేణిలోని స్థానాన్ని తీసివేయలేదు, దాని కంటెంట్లను మాత్రమే. 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 తరగతులు ఉంటే, వాటిలో ప్రతిదానిలో ఒకే లాజిక్తో మనం అదే పద్ధతిని వ్రాయవలసి ఉంటుంది. ఇది మొత్తం విపత్తు -_- కానీ 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='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.ConcurrentModificationExceptionలో 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);
థ్రెడ్ "ప్రధాన" java.utilలో మినహాయింపు 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
}
అవుట్పుట్: పిల్లి{పేరు='థామస్'} పిల్లి{పేరు='బెహెమోత్'} పిల్లి{పేరు='లియోనెల్ మెస్సీ'} పిల్లి{పేరు='మెత్తటి'} మీరు చూడగలిగినట్లుగా, ఇది ఇప్పటికే ఒక 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);
అవుట్పుట్: [Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Fluffy'}] మేము ఇటరేటర్ పద్ధతిలోremove()
సూచిక లేదా పేరును పేర్కొనలేదని మీరు గమనించి ఉండవచ్చు ! ఇటరేటర్ కనిపించే దానికంటే తెలివిగా ఉంది: remove()
ఇటరేటర్ ద్వారా తిరిగి వచ్చిన చివరి మూలకాన్ని తొలగిస్తుంది. మీరు చూడగలిగినట్లుగా, ఇది మేము ఏమి చేయాలనుకుంటున్నామో అదే చేసింది :) సూత్రప్రాయంగా, ఇది ఒక నుండి మూలకాలను తీసివేయడం గురించి మీరు తెలుసుకోవలసిన ప్రతిదీ ArrayList
. బాగా, దాదాపు ప్రతిదీ. తరువాతి పాఠంలో, మేము ఈ తరగతి లోపల చూస్తాము మరియు వివిధ మెథడ్ కాల్ల సమయంలో అక్కడ ఏమి జరుగుతుందో చూద్దాం :) అప్పటి వరకు!
GO TO FULL VERSION