增强for循环原理详解

增强for循环

本质是采用了迭代器,并使用局部变量指向迭代器当前遍历到的元素,使用增强for循环时,无法修改集合当前索引位置的引用,但是如果元素是引用数据类型,那么是可以修改这个元素的信息的(String除外,因为String比较特殊,是不可变的,每次修改都会在常量池中新建一个对象出来)

测试遍历

java 复制代码
public static void main(String[] args) {
    List list=new ArrayList();
    list.add("a");
    list.add("f");
    list.add("j");
    list.add("k");
    //使用增强for循环遍历集合
    for (Object value:list){
        System.out.println(value);
    }

}

增强for循环的局部变量仅用于接收集合元素,修改obj的值并不能修改集合元素(或者说,不能修改对应的集合索引的引用),想要修改只能用集合里面的方法,其实增强for循环内部仍然使用了迭代器。因为增强for循环获取的仅仅是集合的副本,因此是无法对集合更新的。

看了下面的原理图你应该会理解的:

原理图

总结

所以我们与其说是副本,不如说又新建了一个变量,去引用迭代器遍历到的值,如果元素是基本数据类型则保存的仅仅是值,如果是引用数据类型,就是保存的是地址,我们可以使用这个地址对对应的对象进行操作的,比如修改这个对象的属性等。

但是上面例子中,元素是字符串"",是不可变的,因此增强for循环的局部变量引用是指向了字符串常量池,对这个字符串的更新,会在字符串常量池新创造一个字符串的对象,并不会影响遍历到的元素的内容。

如果是stringBuffer或者StringBuilder,我们使用append方法去修改,是可以修改成功的。而为什么我们无法修改当前遍历到的索引的元素,你难道没发现吗,我们缺少了一个索引啊(所以如果我们要修改集合对应位置的引用,可以使用普通for循环,也可以使用迭代器,迭代器的索引是内置的,不对外暴露,因此我们可以直接使用迭代器.remove去移除当前遍历到的元素),但是依然不建议在增强for循环当中去修改集合的引用。

为了验证我上面的结论,这里我演示一遍使用stringBuffer来测试增强for循环进行修改元素值

java 复制代码
public class MyTest {
    public static void main(String[] args) {
        List<StringBuffer> list =new ArrayList<StringBuffer>();
        list.add(new StringBuffer("hello"));
        list.add(new StringBuffer("tsdfa"));
        list.add(new StringBuffer("fdasfh"));
        list.add(new StringBuffer("wrodl"));
        //增强for
        for (StringBuffer stringBuffer : list) {
            //这里我把每一个stringBuffer元素的内容都清除掉(把所有字符都替换成空串,相当于清除)
            stringBuffer.replace(0,stringBuffer.length(), "");
            //然后拼上新的内容
            stringBuffer.append("111111111");
        }
        //再遍历一遍
        for (int i=0;i<list.size();i++){
            System.out.println(list.get(i).toString());
        }
    }
}

运行结果

到此,你应该能理解增强for循环所说的,"不能修改",是不能修改什么东西了吧,不能修改集合当前遍历到索引位置的值(你可以理解为,不能对这个集合进行任何的改动,比如删除元素,增加元素,修改指定索引位置上保存的引用)!而不是不能修改遍历到的元素内部信息。

相关推荐
A阳俊yi20 分钟前
Spring Boot日志配置
java·spring boot·后端
苹果酱056720 分钟前
2020-06-23 暑期学习日更计划(机器学习入门之路(资源汇总)+概率论)
java·vue.js·spring boot·mysql·课程设计
岫珩27 分钟前
“由于启动计算机时出现了页面文件配置问题,Windows在你的计算机上创建了一个临时页面文件。。。”的问题解决
windows
echo1754251 小时前
Apipost免费版、企业版和私有化部署详解
java
异常君1 小时前
Java 高并发编程:等值判断的隐患与如何精确控制线程状态
java·后端·代码规范
异常君1 小时前
Java 日期处理:SimpleDateFormat 线程安全问题及解决方案
java·后端·代码规范
都叫我大帅哥1 小时前
Spring AI中的ChatClient:从入门到精通,一篇搞定!
java·spring·ai编程
都叫我大帅哥1 小时前
《@SpringBootApplication:Spring Boot的"一键启动"按钮,还是程序员的"免死金牌"?》
java·后端·spring
triticale1 小时前
P12167 [蓝桥杯 2025 省 C/Python A] 倒水
java·蓝桥杯
李菠菜1 小时前
解决Windows系统下Git克隆时报错“unable to checkout working tree”的方法详解
windows·git