增强for循环和迭代对集合操作的简单比较

  java集合类的使用可以说是无处不在,总的我们可以将之分为三大块,分别是从Collection接口延伸出的List、Set和以键值对形式作存储的Map类型集合。
     许多情况需要我们遍历出集合中的元素,并做相应的处理。
     下面对各种类型的集合的遍历做一些总结,关于增强for循环,需要注意的是,使用增强for循环无法访问数组下标值,对于集合的遍历其内部采用的也是Iterator的相关方法。如果只做简单遍历读取,增强for循环确实减轻不少的代码量。
关于List与Set类型集合的遍历:
[java] 
import java.util.ArrayList;  
import java.util.HashSet;  
import java.util.Iterator;  
import java.util.List;  
import java.util.Set;  
  
public class ListAndSetTest {  
  
    public static void main(String[] args) {  
        // List集合的遍历  
        listTest();  
        // Set集合的遍历  
        setTest();  
    }  
  
    private static void setTest() {  
        Set set = new HashSet();  
        set.add("JAVA");  
        set.add("C");  
        set.add("C++");  
        // 重复的加不进去。  
        set.add("JAVA");  
        set.add("JAVASCRIPT");  
  
        //set集合遍历方法1,使用iterator  
        Iterator it = set.iterator();  
        while (it.hasNext()) {  
            String value = it.next();  
            System.out.println(value);  
        }  
          
        //set集合遍历方法2,使用增强for循环。  
        for(String s: set){  
            System.out.println(s);  
        }  
    }  
  
    // 遍历list集合  
    private static void listTest() {  
        List list = new ArrayList();  
        list.add("java111");  
        list.add("java222");  
        list.add("java333");  
        list.add("java444");  
        list.add("java555");  
  
        // 遍历方式1 ,使用iterator  
        Iterator it = list.iterator();  
        while (it.hasNext()) {  
            String value = it.next();  
            System.out.println(value);  
        }  
  
        // 遍历方法2 , 使用传统for循环进行遍历。  
        for (int i = 0, size = list.size(); i < size; i++) {  
            String value = list.get(i);  
            System.out.println(value);  
        }  
  
        // 遍历方法3 , 使用增强for循环进行遍历。  
        for (String value : list) {  
            System.out.println(value);  
        }  
    }  
}  
 
关于Map类型集合的遍历,keySet()与entrySet()方法:
[java] view plaincopy
//增强For循环  
public class MapTest {  
  
    public static void main(String[] args) {  
        // 创建一个HashMap对象,并加入了一些键值对。  
        Map maps = new HashMap();  
        maps.put("111", "java111");  
        maps.put("222", "java222");  
        maps.put("333", "java333");  
        maps.put("444", "java444");  
        maps.put("555", "java555");  
          
        // 传统的遍历map集合的方法1; keySet()  
        //traditionalMethod1(maps);  
        // 传统的遍历map集合的方法2; entrySet()  
        //traditionalMethod2(maps);  
        // 使用增强For循环来遍历map集合方法1; keySet()  
        //strongForMethod1(maps);  
        // 使用增强For循环来遍历map集合方法2; entrySet()  
        strongForMethod2(maps);  
    }  
  
    private static void strongForMethod2(Map maps) {  
        Set> set = maps.entrySet();  
        for (Entry entry : set) {  
            String key = entry.getKey();  
            String value = entry.getValue();  
            System.out.println(key + " : " + value);  
        }  
    }  
  
    private static void strongForMethod1(Map maps) {  
        Set set = maps.keySet();  
        for (String s : set) {  
            String key = s;  
            String value = maps.get(s);  
            System.out.println(key + " : " + value);  
        }  
    }  
  
    // 使用entrySet()方法,获取maps集合中的每一个键值对,  
    private static void traditionalMethod2(Map maps) {  
        Set> sets = maps.entrySet();  
        // 取得迭代器遍历出对应的值。  
        Iterator> it = sets.iterator();  
        while (it.hasNext()) {  
            Map.Entry entry = (Entry) it.next();  
            String key = entry.getKey();  
            String value = entry.getValue();  
            System.out.println(key + " : " + value);  
        }  
    }  
  
    // 使用keySet()方法,获取maps集合中的所有键,遍历键取得所对应的值。  
    private static void traditionalMethod1(Map maps) {  
        Set sets = maps.keySet();  
        // 取得迭代器遍历出对应的值。  
        Iterator it = sets.iterator();  
        while (it.hasNext()) {  
            String key = it.next();  
            String value = maps.get(key);  
            System.out.println(key + " : " + value);  
        }  
    }  
}  
<think>好的,我现在需要详细讲解Java中普通for循环增强for循环Iterator迭代器在操作集合对象时的区别。首先,我得回忆一下这三种遍历方式的基本用法特点,然后逐一比较它们的底层实现、适用场景以及修改集合时的行为差异。 首先,普通for循环是基于索引的,通常用于List这类可以通过索引访问的集合,比如ArrayList。它的结构是初始化索引变量,设置循环条件,然后递增或递减索引。在循环体内,通过get(index)方法获取元素。这种方式可以直接通过索引访问修改集合元素,但可能对LinkedList效率较低,因为LinkedList的get(index)是线性时间操作。 接下来是增强for循环,也称为for-each循环。它在语法上更简洁,适用于所有实现了Iterable接口的集合增强for循环内部实际上是使用了Iterator,编译器会将其转换为Iterator的调用。这意味着用户无需显式地处理迭代器,代码更简洁,但无法直接访问索引,也不能在遍历时修改集合结构(比如删除元素),否则会抛出ConcurrentModificationException异常。 然后是Iterator迭代器,这是一种设计模式,提供了统一的方式来遍历集合。Iterator具有hasNext()、next()、remove()等方法。使用Iterator可以在遍历时安全地删除元素,因为remove()方法会维护集合的一致性。此外,ListIterator还提供了向前遍历修改元素的功能。不过,Iterator不能直接通过索引访问元素,修改元素通常需要结合具体集合的实现。 接下来需要比较它们的区别,包括语法、底层机制、性能、修改元素结构的能力、异常处理以及适用场景。例如,普通for循环适合需要索引操作修改元素的场景,但可能性能较差;增强for循环语法简洁但无法修改结构;Iterator提供了安全的删除操作,但修改元素需要特定方法。 在思考过程中,我需要确认每种遍历方式的优缺点,特别是在修改集合时的情况。例如,普通for循环通过set(index, element)可以修改元素,而增强for循环修改元素变量不会影响原集合,因为操作的是局部变量。Iterator的remove()方法可以安全删除当前元素,但修改元素需要如ListIterator的set()方法。 可能还需要举例说明不同遍历方式在修改集合时的行为差异,比如在ArrayList中使用普通for循环修改元素的高效性,而在LinkedList中使用Iterator可能更高效。此外,需要提到并发修改异常的产生条件如何避免。 最后,总结部分需要明确每种方式的适用情况,帮助用户根据具体需求选择最合适的遍历方法。例如,需要索引时用普通for,只读遍历用增强for,需要删除元素用Iterator等。 现在,我需要将这些思考整理成一个结构清晰、逐步解释的回答,确保涵盖各个方面的区别,并举例说明,同时保持语言简洁易懂。</think>--- 在Java中,普通`for`循环增强`for`循环for-each)`Iterator`迭代器是三种常见的遍历集合对象的方式。它们在语法、底层实现、适用场景及操作限制上存在显著差异。以下是详细对比分析: --- ### **1. 普通`for`循环(基于索引)** **语法示例**: ```java for (int i = 0; i < list.size(); i++) { String element = list.get(i); // 操作元素 } ``` **特点**: 1. **底层机制**: - 通过索引直接访问集合元素(如`list.get(i)`)。 - 适用于所有支持**随机访问**的集合(如`ArrayList`),但对`LinkedList`效率较低(`get(i)`的时间复杂度为$O(n)$)。 2. **修改能力**: - 可通过`set(index, value)`直接修改集合中的元素。 - 可直接删除元素(需注意索引变化),例如: ```java list.remove(i); // 删除后,后续元素索引前移,需手动调整i ``` 3. **适用场景**: - 需要根据索引操作元素(如修改、替换)。 - 需要反向遍历(如`for (int i = list.size()-1; i >=0; i--)`)。 **局限性**: - 对非随机访问的集合(如`LinkedList`)性能差。 - 手动维护索引容易出错(如删除元素后索引未调整)。 --- ### **2. 增强`for`循环for-each循环)** **语法示例**: ```java for (String element : list) { // 操作元素 } ``` **特点**: 1. **底层机制**: - 编译器会将其转换为`Iterator`实现(依赖集合的`iterator()`方法)。 - 适用于所有实现`Iterable`接口的集合(如`List`、`Set`、数组等)。 2. **修改能力**: - **不能直接修改集合结构**(如添加、删除元素),否则抛出`ConcurrentModificationException`。 - 对元素变量的赋值仅改变局部引用,不影响原集合(除非元素是可变对象)。 3. **适用场景**: - 只读遍历,无需索引操作。 - 代码简洁,无需显式处理迭代器。 **局限性**: - 无法获取当前元素的索引。 - 无法在遍历时安全修改集合结构。 --- ### **3. `Iterator`迭代器** **语法示例**: ```java Iterator<String> it = list.iterator(); while (it.hasNext()) { String element = it.next(); // 操作元素 } ``` **特点**: 1. **底层机制**: - 提供统一接口遍历集合,解耦遍历逻辑与集合实现。 - 通过`hasNext()``next()`逐个访问元素。 2. **修改能力**: - **可安全删除元素**:通过`it.remove()`删除当前元素,避免`ConcurrentModificationException`。 - 若使用`ListIterator`,还支持`set()`修改元素`add()`插入元素。 ```java ListIterator<String> lit = list.listIterator(); while (lit.hasNext()) { String element = lit.next(); lit.set("new value"); // 修改当前元素 lit.add("inserted"); // 插入元素 } ``` 3. **适用场景**: - 需要遍历时删除元素(如过滤集合)。 - 需要双向遍历(`ListIterator`支持向前/向后遍历)。 **局限性**: - 无法直接通过索引访问元素。 - 修改元素需依赖特定迭代器(如`ListIterator`)。 --- ### **三者的核心区别对比** | **特性** | 普通`for`循环 | 增强`for`循环 | `Iterator`迭代器 | |------------------------|-----------------------|-----------------------|------------------------| | **语法复杂度** | 需手动管理索引 | 最简洁 | 需显式创建迭代器 | | **底层访问方式** | 索引直接访问元素 | 隐式使用迭代器 | 显式使用迭代器 | | **遍历时修改结构** | 支持,但需处理索引变化 | 不支持(抛出异常) | 支持(通过`remove()`) | | **遍历时修改元素** | 支持(通过`set()`) | 仅限可变对象的属性 | 支持(通过`set()`) | | **性能** | 随机访问集合高效 | 所有集合通用 | 非随机访问集合更高效 | | **适用场景** | 需要索引或反向遍历 | 只读遍历 | 安全删除或复杂操作 | --- ### **示例:修改集合时的行为差异** #### **1. 修改元素值** - **普通`for`循环**:直接通过`set()`生效。 ```java for (int i = 0; i < list.size(); i++) { list.set(i, "modified"); // 修改集合中的元素 } ``` - **增强`for`循环**:仅修改局部变量,原集合不变。 ```java for (String s : list) { s = "modified"; // 无效,原集合未被修改 } ``` - **迭代器**:需使用`ListIterator`的`set()`方法。 ```java ListIterator<String> it = list.listIterator(); while (it.hasNext()) { it.next(); it.set("modified"); // 修改集合中的元素 } ``` #### **2. 删除元素** - **普通`for`循环**:需手动调整索引。 ```java for (int i = 0; i < list.size(); i++) { if (condition) { list.remove(i); i--; // 索引回退 } } ``` - **增强`for`循环**:直接删除会抛出`ConcurrentModificationException`。 - **迭代器**:安全删除。 ```java Iterator<String> it = list.iterator(); while (it.hasNext()) { String s = it.next(); if (condition) { it.remove(); // 安全删除 } } ``` --- ### **总结** - **普通`for`循环**:适合需要索引操作或高效随机访问的场景(如`ArrayList`)。 - **增强`for`循环**:适合只读遍历,代码简洁,但无法修改结构。 - **`Iterator`迭代器**:适合需要安全删除元素或复杂遍历操作的场景,尤其对`LinkedList`等非随机访问集合更高效。 根据具体需求选择合适的遍历方式,可以有效提升代码性能可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值