理解Java中的for-each循环:为什么有时候不能修改数组元素?

前言:

      刚开始学习编程的时候,我们都会老老实实用 for-i循环,后面接触到for-each的时候,发现竟然还可以再省一点代码,慢慢也会开始学会用for-each。但其实,在有些即使是需要从头遍历的场景,for-each也并不能替代for-i循环,例如修改遍历基本数据类型的数组元素。 


目录

一、分析数组类型:int[ ] 

二、分析数组类型:String[ ]

三、分析StringBuilder[ ]类型,有时可以改 

四、归纳总结:


一、分析数组类型:int[ ] 

public static void main(String[] args) {
        int[] numbers = new int[5];

        System.out.print("修改前:");
        //用for-each遍历输出,看看原数组
        for (int number : numbers) {
            System.out.print(number);
        }

        //用for-each遍历修改
        for (int number : numbers) {
           number=1;
        }
        System.out.println();
        System.out.print("修改后:");
        //用for-each遍历输出,看看修改结果
        for (int number : numbers) {
            System.out.print(number);
        }

如图所示,修改失败。

原因: 

当我们在for-each循环中遍历数组时,循环体中的变量(如上例中的number实际上只是数组元素的一个副本而不是对原数组元素的引用。只是把number这个局部变量的值改了,

循环体中的变量是一个局部变量,它的生命周期仅限于一次循环迭代。

 为什么for-i行? 

 number[i] 通过索引访问的是数组中的实际元素的引用,修改它就会改变原数组中的数据。


二、分析数组类型:String[ ]

原因: 

      在 for-each 循环中,循环变量 tmp 只是一个指向数组元素的局部引用。对 tmp 重新赋值只会改变 tmp 自身的指向,并不会修改数组中实际元素的引用,因此数组内容保持不变。


三、分析StringBuilder[ ]类型,有时可以改 

原因: 

   append 方法可以修改 StringBuilder 对象的内容,因为 StringBuilder 是可变对象,append 直接改变对象的内部状态

         而 = 赋值仅改变了 tmp 变量的引用,指向了新的对象,不会影响原数组中的 StringBuilder 对象,因此无法修改数组中的内容。


四、归纳总结: 

1.针对基本数据类型:int[] 和其他基本数据类型的数组(如 byte[], char[], float[] 等)都具有相似的特性。在这些数组中,for-each`循环只会遍历元素的副本,而不是数组元素的引用,使用 for-each循环进行修改都不会影响原数组的内容。

2.针对引用类型:针对引用类型的数组,for-each`循环提供的是一个局部变量该变量是数组中元素引用的拷贝

- 如果在循环中使用 `=` 操作符,只会改变这个局部变量指向的对象引用,而不会影响原数组中的引用。

- 只有通过对这个对象调用方法,或者直接修改对象的属性(如 `TreeNode.next`),才能真正影响到原数组中的元素。

就像我们做一些链表Oj,题中链表头结点为head

我们让cur=head;

再让cur=null;

并不会影响原链表。

但是我们让cur=head;

再让cur.next=null;

就影响到了原链表了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值