关于Java集合类迭代变量的修改

来源:互联网 发布:mac 双重认证 编辑:程序博客网 时间:2024/06/05 18:39

前几天和一个同事关于一个议题产生了疑虑:Java中对于集合类迭代变量的修改是否会影响原集合。

有的书中信誓旦旦的说,修改集合类的迭代变量是毫无意义的,比如李刚的《疯狂Java讲义》;而同事反馈说,在实际编程时,修改了迭代变量发现原集合也变了。

那么修改迭代变量到底会不会影响原集合呢?

当时我的第一反应是,这可能和传值/传引用有关,他们说的可能不是一个东西。周末稍微有点空闲,就仔细琢磨了下这个问题。

首先我们来看一段代码

import java.util.List;import java.util.ArrayList;public class Test1{public static void main(String[] args){List<String> books = new ArrayList<String>();books.add("Crazy Java");books.add("Head First Python");books.add("Coding with me");//第一次输出,输出修改迭代变量前的集合System.out.println(books);for (String book : books){book = "test";}//第二次输出,输出修改迭代变量后的集合System.out.println(books);}}


程序运行结果如下:



两次输出结果一致,修改迭代变量后,集合内容没变。似乎书上说的没错。

我们再来看一段代码:

import java.util.List;import java.util.ArrayList;class Book{private String name;private float price;public Book(){}public Book(String name,float price){this.name = name;this.price = price;}public String getName(){return this.name;}public float getPrice(){return this.price;}public void setName(String name){this.name = name;}public void setPrice(float price){this.price = price;}public String toString(){return this.name+"\t"+this.price;}}public class Test2{public static void main(String[] args){List<Book> books = new ArrayList<Book>();Book book1 = new Book("Thinking in Java",50);Book book2 = new Book("Thinking in C++",51);Book book3 = new Book("Head First Python",52);/*add all thest books to the ArrayList*/books.add(book1);books.add(book2);books.add(book3);System.out.println(books);/*try to change the Arraylist*/for(Book book : books){book.setPrice(0);}System.out.println(books);}}

运行结果:

显然,这次修改迭代变量后,原集合变了。

那到底修改迭代变量会不会改变原集合呢?

其实仔细观察这两段代码,可以发现问题的本质,这两次对迭代变量的“修改”是不一样的。

第一段代码中,修改的是迭代变量本身,即让迭代变量指向(或者说引用)了新的对象,而并没有修改迭代变量引用的对象,所以集合中的内容当然没变。

第二段代码中,其实恰恰相反,其实我们并没有修改迭代变量本身,book变量依然指向集合中的该对象,我们修改的是book变量指向的对象,所以哦集合中的内容自然就变了。

其实编程语言本质上是共通的,此处Java中迭代变量book就是C/C++中的指针,我们传递给book的是对象的地址(或者说引用)而不是对象本身,我们修改指针变量本身的值,并不会影响到指针指向的内容,就像第一段代码中那样。

但是我们如果修改指针指向的地址中的内容,就像第二段代码中那样,内容本身也就变了

 

1 0
原创粉丝点击