1. Background kung paano naging mga iterator

Pamilyar ka na sa HashSet. Kung talagang inimbestigahan mo ito, higit sa pagbabasa lamang ng isang aralin, dapat ay tinanong mo ang tanong na ito:

Paano ako magpapakita ng listahan ng lahat ng elemento ng HashSet sa screen? Pagkatapos ng lahat, ang interface ay walang get()at set()mga pamamaraan!

At HashSethindi nag-iisa sa limitasyong ito. Bilang karagdagan sa HashSet, mayroong maraming iba pang mga koleksyon na hindi pinapayagan ang mga elemento na makuha ng index, dahil ang mga elemento ay walang tinukoy na pagkakasunud-sunod.

Sa paglipas ng mga taon, ang mga programmer ay nakaimbento ng maraming kumplikadong istruktura ng data, tulad ng mga graph at puno. O mga listahan ng mga listahan.

Binabago ng maraming container ang pagkakasunud-sunod ng kanilang mga elemento kapag nagdagdag ng mga bagong elemento o inalis ang mga kasalukuyang elemento. Halimbawa, ang isang listahan ay nag-iimbak ng mga elemento sa isang partikular na pagkakasunud-sunod, at kapag may idinagdag na bagong elemento, ito ay halos palaging ipinapasok sa gitna ng listahan.

At nakakakuha din kami ng mga sitwasyon kung saan mayroong isang lalagyan na nag-iimbak ng mga elemento ngunit hindi sa anumang nakapirming pagkakasunud-sunod.

Ngayon sabihin nating gusto nating kopyahin ang lahat ng mga elemento mula sa naturang koleksyon sa isang array o listahan. Kailangan nating makuha ang lahat ng mga elemento. Wala kaming pakialam sa pagkakasunud-sunod kung saan kami umulit sa mga elemento — ang mahalagang bagay ay hindi umulit sa parehong mga elemento nang higit sa isang beses. Paano natin gagawin iyon?


2. Iterator para sa isang koleksyon

Ang mga iterator ay iminungkahi bilang isang solusyon sa problema sa itaas.

Ang iterator ay isang espesyal na bagay na nauugnay sa isang koleksyon, na tumutulong sa pagtawid sa lahat ng mga elemento ng koleksyon nang hindi umuulit ng anuman.

Maaari mong gamitin ang sumusunod na code upang makakuha ng isang iterator para sa anumang koleksyon:

Iterator<Type> it = name.iterator();

Nasaan nameang pangalan ng variable ng koleksyon, Typeang uri ng mga elemento ng koleksyon, iterator()ay isa sa mga pamamaraan ng koleksyon, at itang pangalan ng variable ng iterator.

Ang isang iterator object ay may 3 pamamaraan:

Pamamaraan Paglalarawan
Type next()
Ibinabalik ang susunod na elemento sa koleksyon
boolean hasNext()
Sinusuri kung mayroong anumang mga elemento na hindi pa nadadaanan
void remove()
Inaalis ang kasalukuyang elemento ng koleksyon

Ang mga pamamaraang ito ay medyo katulad ng mga klase nextInt)at hasNextInt()pamamaraan ng Scanner.

Ibinabalik ng next()pamamaraan ang susunod na elemento ng koleksyon kung saan nakuha namin ang iterator.

Sinusuri ng hasNext()pamamaraan kung ang koleksyon ay may mga karagdagang elemento na hindi pa naibabalik ng iterator.

Narito kung paano ipakita ang lahat ng mga elemento ng isang HashSet:

Code Mga Tala
HashSet<String> set = new HashSet<String>();

set.add("Hallo");
set.add("Hello");
set.add("Hola");
set.add("Bonjour");
set.add("Ciao");
set.add("Namaste");

Iterator<String> it = set.iterator();
while (it.hasNext())
{
   String str = it.next();
   System.out.println(str);
}
Lumikha ng isang HashSetbagay na nag-iimbak Stringng mga elemento.


Nagdaragdag kami ng mga pagbati sa iba't ibang wika sa setvariable.




Kumuha ng iterator object para sa setset.
Hangga't may mga elemento pa

Kunin ang susunod na elemento
Ipakita ang elemento sa screen


3. For-eachloop

Ang pangunahing kawalan ng isang iterator ay ang iyong code ay nagiging mas mahirap kaysa sa paggamit ng isang forloop.

Upang ihambing, magpakita tayo ng isang listahan gamit ang isang forloop at gumagamit din ng isang iterator:

Tagapag-ulit para sa loop
ArrayList<String> list = new ArrayList<String>();

Iterator<String> it = list.iterator();
while (it.hasNext())
{
   String str = it.next();
   System.out.println(str);
}
ArrayList<String> list = new ArrayList<String>();

for (int i = 0; i < list.size(); i++)
{
   String str = list.get(i);
   System.out.println(str);
}

Oo, mas mainam na lampasan ang mga elemento ng ArrayListpaggamit ng loop — mas maikli ang lahat.

Ngunit muling nagpasya ang mga tagalikha ng Java na magbuhos ng asukal sa amin. Sa kabutihang-palad para sa amin, ito ay syntactic sugar .

Binigyan nila ang Java ng bagong uri ng loop at tinawag itong for-eachloop. Ganito ang hitsura nito sa pangkalahatan:

for(Type name:collection)

Nasaan collectionang pangalan ng variable ng koleksyon, Typeang uri ng mga elemento sa koleksyon, at nameang pangalan ng variable na kumukuha ng susunod na halaga mula sa koleksyon sa bawat pag-ulit ng loop.

Ang ganitong uri ng loop ay umuulit sa lahat ng elemento ng isang koleksyon gamit ang isang implicit iterator. Ganito talaga ito gumagana:

Para sa-bawat loop Ano ang nakikita ng compiler: Loop na may isang iterator
ArrayList<String> list = new ArrayList<String>();

for (String str: list)
{
   System.out.println(str);
}
ArrayList<String> list = new ArrayList<String>();
Iterator<String> it = list.iterator();

while (it.hasNext())
{
   String str = it.next();
   System.out.println(str);
}

Kapag nakatagpo ang compiler ng for-eachloop sa iyong code, papalitan lang ito ng code sa kanan: nagdadagdag ito ng tawag para makakuha ng iterator kasama ng anumang iba pang nawawalang method na tawag.

Gustung-gusto ng mga programmer ang for-eachloop at halos palaging ginagamit ito kapag kailangan nilang umulit sa lahat ng elemento ng isang koleksyon.

Kahit na ang pag-ulit sa isang ArrayListlistahan gamit ang isang for-eachloop ay mukhang mas maikli:

Para sa-bawat loop para sa loop
ArrayList<String> list = new ArrayList<String>();

for (String str: list)
{
   System.out.println(str);
}
ArrayList<String> list = new ArrayList<String>();

for (int i = 0; i < list.size(); i++)
{
   String str = list.get(i);
   System.out.println(str);
}


4. Pag-alis ng elemento sa isang for-eachloop

Ang for-eachloop ay may isang sagabal: hindi nito maalis nang tama ang mga elemento. Kung sumulat ka ng code na tulad nito, magkakaroon ka ng error.

Code Tandaan
ArrayList<String> list = new ArrayList<String>();

list.add("Hallo");
list.add("Hello");
list.add("Hola");
list.add("Bonjour");
list.add("Ciao");
list.add("Namaste");

for (String str: list)
{
   if (str.equals("Hello"))
      list.remove(str);
}












Ang pagpapatakbo ng pag-alis ay bubuo ng isang error!

Ito ay isang napakaganda at naiintindihan na code, ngunit hindi ito gagana.

Mahalaga!

Hindi mo maaaring baguhin ang isang koleksyon habang binabagtas mo ito gamit ang isang iterator.

May tatlong paraan upang malagpasan ang limitasyong ito.

1. Gumamit ng ibang uri ng loop

When traversing an ArrayList collection, maaari kang gumamit ng ordinaryong loop na may icounter variable.

Code
for (int i = 0; i < list.size(); i++)
{
   String str = list.get(i);

   if (str.equals("Hello"))
   {
      list.remove(str);
      i--; // We need to decrease i, because the remove operation shifted the elements
   }
}

Gayunpaman, ang pagpipiliang ito ay hindi angkop para sa HashSetat HashMapmga koleksyon

2. Gumamit ng isang tahasang iterator

Maaari kang gumamit ng isang iterator nang tahasan at tawagan ang remove()pamamaraan nito.

Bersyon na gumagana Bersyon na hindi gumagana
Iterator<String> it = set.iterator();
while (it.hasNext())
{
   String str = it.next();
   if (str.equals("Hello"))
       it.remove();
}

for (String str: list) { if (str.equals("Hello")) list.remove(str); }

Tandaan na tinatawag namin ang remove()pamamaraan sa object ng iterator! Alam ng iterator na naalis na ang item at kayang hawakan nang tama ang sitwasyon.

3. Gumamit ng kopya ng koleksyon

Maaari ka ring lumikha ng isang kopya ng koleksyon at pagkatapos ay gamitin ang kopya sa isang for-eachloop at tanggalin ang mga elemento mula sa orihinal na koleksyon.

Code Tandaan
ArrayList<String> listCopy = new ArrayList(list);

for (String str: listCopy)
{
   if (str.equals("Hello"))
      list.remove(str);
}
Ang paggawa ng kopya ng isang koleksyon ay napakadali



Ang loop ay gumagamit ng iterator para sa kopya ng koleksyon.
Ang mga elemento ay tinanggal mula sa listkoleksyon.

Ang koleksyon ay kinopya sa halip mabilis, dahil ang mga elemento mismo ay hindi nadoble. Sa halip, ang bagong koleksyon ay nag-iimbak ng mga sanggunian sa mga elementong umiiral na sa lumang koleksyon.