forEach对原数组的操作

这篇博客探讨了Java中forEach循环在处理基本数据类型和引用数据类型时的行为。对于基本类型,如int和double,forEach遍历过程中无法修改原数组的值。而对于引用类型,特别是String,由于其不可变性,forEach同样不能修改原数组。然而,对于其他非final修饰的引用类型,如StringBuilder,可以在遍历过程中修改其属性,因为forEach操作的是引用地址。博客还强调了在使用equals()比较StringBuilder时的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

forEach

总结
forEach对于基本数据类型,是直接赋值,对于引用数据类型,是引用地址值。

  1. 对于基本数据类型,forEach不能修改原数组的值。
  2. .对于引用数据类型:String,forEach也不能修改原数组的值,因为String是不可变的。
  3. 对于其他引用类型(不被final修饰),forEach能修改具体的属性,因为forEach是地址引用。

forEach遍历时,是创建的临时变量,引用的数据地址。
对于基本数据类型,int,char,double等,这些值在forEach中进行遍历操作时,是不能修改的。

	@Test
    public void testInt(){
        int[] arr = new int[]{1,2,3,4,5};

        //使用foreach遍历arr数组
        for(int i : arr){
            //如果i=2,那么就将i值变为0
            if(i == 2){
                i = 0;
            }
        }

        //遍历数组
        for(int i : arr){
            System.out.print(i + " ");
        }

对于以上代码,我们预期输出是1 0 3 4 5,但是实际输出是1 2 3 4 5
在这里插入图片描述
forEach在遍历基本数据类型是,相当于是创建了一个临时变量i,我们相对数组元素的修改,实际上都是修改的i值,并不会影响原数据
对于引用数据类型:
特殊:String类:
对于String类,也是不能修改的,因为String是被final修饰,是不可变的。

 	@Test
    public void testString(){
        String[] strAll = new String[]{"aa","bb","cc"};
        for(String str : strAll){
            if("bb".equals(str)){
                str = "xx";
            }
        }
        for(String str : strAll){
            System.out.print(str + " ");
        }
    }

对于以上代码,我们预期输出是 aa xx cc ,但是实际输出确实 aa bb cc
在这里插入图片描述
开始时内存空间解析:
在这里插入图片描述
后面str依次指向aa bb cc
在这里插入图片描述
当指向bb时,他想修改其中的值,但是String是不能被修改的,所以他只能重新去创建一个1,但是原数组的指向并没变。,所以最后遍历踹的原数组值也是不会改变的。
在这里插入图片描述
对于其他引用类:
例如StringBuilder:
需要注意的是,StringBuilder并没有重写equals()方法,所以在进行equals比较时,只能转化成String来比较。

@Test
    public void testStringBuilder(){
        StringBuilder[] strBul = new StringBuilder[]{new StringBuilder("111"), new StringBuilder("222"), new StringBuilder("333")};

        for(StringBuilder s : strBul){
            //StringBuilder并没有重写equals,所以如果直接调用的话,它是比较的地址值。
            if("222".equals(s.toString())){
                s.append("aaa");
            }
        }

        for(StringBuilder s : strBul){
            System.out.println(s);
        }

预期输出和实际输出都是 111 222aaa 333
在这里插入图片描述
我们自己定义的类:

public class TestForeach {
   
    Person[] pArr = new Person[]{new Person("张三",18),new Person("李四",20),new Person("王六",10)};
    public void foreachTestPerson(){
        for(Person p : pArr){
            if("王六".equals(p.name)){
                p.age = 100;
            }
        }

        for(Person p : pArr){
            System.out.println(p);
        }
    }

    public static void main(String[] args) {
        new TestForeach().foreachTestPerson();
    }
}

class Person{
    public String name;
    public int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", id=" + age +
                '}';
    }
}

在这里插入图片描述
特别需要注意:StringBuilder和StringBuffer都是没有重写equals()方法的,不要直接用equals比较!
内存解析:
开始时:
在这里插入图片描述
修改后,原数组的地址时没有变的,所以能修改成功。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值