Collection接口遍历元素方式

使用Iterator(迭代器)

In computer programming, an iterator is an object that progressively provides access to each item of a collection, in order.

  1. Iterator 对象称为迭代器,主要用于遍历Collection集合中的元素。
  2. 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回一个迭代器。
  3. Iterator的结构.
  4. Iterator仅用于遍历集合,Iterator本身并不存放对象。

执行原理:

Iterator iterator = new coll.iterator(); // 得到一个集合的迭代器
// hasNext(); 判断是否还有下一个元素
while(iterator .hasNext()){
//next0作用:1.下移2.将下移以后集合位置上的元素返回
	System.out.println(iterator.next());
}

在调用iterator.next()方法之前必须要调用 iterator.hasNext() 进行检测。若不调用,且下一条记录无效,直接调用iterator.next()会抛出 NoSuchElementException 异常。

for 循环增强

增强for循环,可以代替iteratori迭代器,特点:增强for就是简化版的literator,本质一样。只能用于遍历集合或数组。

for(元素类型 元素名 : 集合名或数组名){
		访问元素
}

import java.util.ArrayList;
import java.util.Iterator;
 
public class IteratorExample {
    public static void main(String[] args) {
        ArrayList<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Orange");
 
        // Get an Iterator for the ArrayList
        Iterator<String> fruitIterator = fruits.iterator();
 
        // Loop through the collection using the Iterator
        while (fruitIterator.hasNext()) {
            String fruit = fruitIterator.next();
            System.out.println(fruit);
 
            // Example of removing an element during iteration
            if (fruit.equals("Banana")) {
                fruitIterator.remove(); 
            }
        }
        System.out.println("After removal: " + fruits);
    }
}
  • remove():
    This optional method removes the last element returned by next() from the underlying collection. This method can only be called once per next() call and throws an IllegalStateException if called without a preceding next() call or if remove() has already been called for the current element.

// draw EnemyTank and bullets that they shoot  
for(EnemyTank enemyTank: enemyTanks){  
    drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirection(), 1);  
    for (Shot shot: enemyTank.getShotsVector()){  
        if(shot.isAlive) {  
            g.fill3DRect(shot.x, shot.y, 5,5,false);  
        } else{  
            // 从 Vector 移除  
            enemyTank.getShotsVector().remove(shot);  
        }  
    }  
}

这段代码报错

for (Shot shot : enemyTank.getShotsVector()) {
    if (shot.isAlive) {
        g.fill3DRect(shot.x, shot.y, 5,5,false);
    } else {
        // 从 Vector 移除
        enemyTank.getShotsVector().remove(shot); // ❌ 在遍历中修改 Vector
    }
}

你在使用增强 for 循环遍历 Vector<Shot> 的同时,又对其进行了 remove() 操作。这在 Java 中是不允许的,会导致运行时报错:
java.util.ConcurrentModificationException
类似于:

Vector<String> names = new Vector<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
 
// 增强for循环遍历的同时删除元素
for (String name : names) {
		if (name.equals("Bob")) {
				names.remove(name); // ❌ 遍历过程中修改Vector,抛异常
		}
}

大致原理:

public class ArrayList implements List{
 
	transient int modCount = 0; // 维护了成员变量,记录 ArrayList 修改的次数
 
	public boolean add(Object e){
		modCount++;
		// ... 省略其他逻辑
		return true;
	}
 
	public boolean remove(Object o){
		modCount++;
		// ... 省略其他逻辑
		return true;
	}
 
	// ... 省略其他逻辑
 
	// 返回新的迭代器
	public Iterator<E> iterator(){
		return new Itr();
	}
 
	private class Itr implements Iterator{
		// 复制集合的 modCount
		int expectedModCount = modCount;
 
		public Object next(){
			if (modCount != expectedModCount)
				throw new ConcurrentModificationException();
				// ... 省略其他逻辑
		}
	}
}

迭代器在遍历元素时,会检查 modCount 是否鹤当初保存的数值一致,如果不一致就代表集合在获取迭代器之后,进行了增删操作,此时迭代器就抛物异常。

相似解决办法:

Vector<String> names = new Vector<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
 
// 使用 Iterator 遍历并安全删除
Iterator<String> it = names.iterator();
while (it.hasNext()) {
	String name = it.next();
	if (name.equals("Bob")) {
			it.remove(); // ✅ 安全删除
	}
}