Una operación no tan común como la de nuestro anterior Tip #1 pero igual de necesaria en algunas ocasiones. Como eliminamos un elemento mientras recorremos una lista?
En alguna ocasión el instinto de novato nos ha llevado a hacer algo como esto:
1
2
3
4
5
6
7
8
9
10
11
12
13
List<Integer> lista = new ArrayList<Integer>();
//LLenamos la lista para el ejemplo
for(int index = 0; index < 10; index++){
lista.add(index);
}
//Ahora tratamos de eliminar el elemento 5
for (Integer item : lista) {
if(item.equals(5)){
lista.remove(item);
}
}
Y bingo nos da una excepción de concurrencia como esta Exception in thread "main" java.util.ConcurrentModificationException
.
Aquí es donde aparecen los iteradores. La interface Iterator
es nuestra amiga para esta operación, de hecho es la única forma segúra de remover o modificar una colección mientras la recorremos. Toda clase e interface que implemente o extienda de Iterable<T>
retorna un Iterator
.
La interface Collection
extiende de Iterable
y por ende, todas sus subinterfaces List
, Set
, Queue
tiene acceso a un Iterator
.
Eliminar un elemento
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
List<Integer> lista = new ArrayList<Integer>();
//LLenamos la lista para el ejemplo
for(int index = 0; index < 10; index++){
lista.add(index);
}
//Ahora eliminamos el elemento 5
Iterator<Integer> iterator = lista.iterator();
while (iterator.hasNext()){
Integer item = iterator.next();
if(item.equals(5)){
iterator.remove();
}
}
Y que pasa con Map
?
Podmemos sacar el Iterator
del Set
de entries del mapa:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Map map = new HashMap<>();
//LLenamos el mapa para el ejemplo
for(int index = 0; index < 10; index++){
map.put(index, index);
}
//Ahora eliminamos el elemento 5
Set entrySet = map.entrySet();
Iterator iterator = entrySet.iterator();
while (iterator.hasNext()){
Map.Entry item = (Map.Entry) iterator.next();
if(item.getKey().equals(5)){
iterator.remove();
}
}