Hoe kan ik een element in List toevoegen terwijl het itereert in Java?

Stel dat ik een lijst heb zoals:

List list = new ArrayList<>();
list.add("a");
list.add("h");
list.add("f");
list.add("s");

Terwijl ik door deze lijst heenloop, wil ik een element aan het einde van de lijst toevoegen. Maar ik wil niet door de nieuw toegevoegde elementen herhalen dat wil ik herhalen tot de oorspronkelijke grootte van de lijst.

for (String s : list)
     /* Here I want to add new element if needed while iterating */

Kan iemand me voorstellen hoe kan ik dit doen?

24

5 antwoord

Je kunt daarvoor geen foreach-verklaring gebruiken. Foreach gebruikt intern een iterator:

De iterators die door de iterator en listIterator van deze klasse zijn geretourneerd   methoden zijn fail-fast: als de lijst structureel is aangepast op om het even welk   tijd nadat de iterator is gemaakt, op welke manier dan ook, behalve via de   iterator's eigen methoden voor verwijderen of toevoegen, de iterator zal a gooien   ConcurrentModificationException.

(Van ArrayList javadoc)

In de foreach-instructie heeft u geen toegang tot de iteratormethode voor het toevoegen en in elk geval is dat nog steeds niet het type add dat u wilt, omdat het niet aan het einde wordt toegevoegd. U moet de lijst handmatig doorlopen:

int listSize = list.size();
for(int i = 0; i < listSize; ++i)
  list.add("whatever");

Merk op dat dit alleen efficiënt is voor lijsten die willekeurige toegang toestaan. U kunt op deze functie controleren door te controleren of de lijst de RandomAccess-markeringsinterface implementeert. Een ArrayList heeft willekeurige toegang. Een gelinkte lijst doet dat niet.

35
toegevoegd

Herhaal gewoon de ouderwetse manier, want je hebt een expliciete indexafhandeling nodig:

List myList = ...
...
int length = myList.size();
for(int i = 0; i < length; i++) {
   String s = myList.get(i);
  //add items here, if you want to
}
8
toegevoegd
Doh! Slechte lectuur van mijn kant.
toegevoegd de auteur Tony Ennis, de bron
Nee, dat zal het niet. Dit zal het geval zijn bij gebruik van een iterator en het toevoegen van alements terwijl het itereert, maar niet als het hier alleen gaat om iteratie.
toegevoegd de auteur Fabian Barney, de bron
OP's wil "om de oorspronkelijke grootte te herhalen".
toegevoegd de auteur Fabian Barney, de bron

Herhaal via een kopie van de lijst en voeg nieuwe elementen toe aan de oorspronkelijke lijst.

for (String s : new ArrayList(list))     
{
    list.add("u");
}

See How to make a copy of ArrayList object which is type of List?

6
toegevoegd

U kunt een kopie (kloon) van uw oorspronkelijke lijst herhalen:

List copy = new ArrayList(list);
for (String s : copy) {
   //And if you have to add an element to the list, add it to the original one:
    list.add("some element");
}

Merk op dat het zelfs niet mogelijk is om een ​​nieuw element toe te voegen aan een lijst terwijl het erop itereert, omdat het zal resulteren in een ConcurrentModificationException .

2
toegevoegd

Ik doe dit door de elementen toe te voegen aan een nieuwe, lege tmp-lijst en vervolgens de tmp-lijst toe te voegen aan de oorspronkelijke lijst met behulp van addAll() . Hiermee wordt voorkomen dat een grote bronlijst onnodig wordt gekopieerd.

Stel je voor wat er gebeurt als de originele lijst van het OP een paar miljoen items bevat; een tijdje zul je twee keer het geheugen leegzuigen.

Naast het besparen van bronnen, voorkomt deze techniek ook dat we onze toevlucht moeten nemen tot de 80s-stijl voor loops en het gebruik van wat eigenlijk arrayindices zijn die in sommige gevallen onaantrekkelijk zouden kunnen zijn.

0
toegevoegd