小弟看书自学,看到java集合这里有点疑问,想了很久也上机试了还是搞不明白,求大神们指点!
import java.util.*;
public class IteratorTest
{
public static void main(String[] args)
{
Collection books = new HashSet();
books.add(new String("Java EE"));
books.add(new String("IOS"));
books.add(new String("Android"));
System.out.println(books);
Iterator it = books.iterator();
String b = (String)it.next(); //①
b = "aaa";
System.out.println(books);
}
}
这段代码是我用书上的范例改了改,运行结果如下:
[Android, IOS, Java EE]
[Android, IOS, Java EE]对应的这段代码书上是这么讲解的:
当使用Iterator对集合元素进行迭代时,Iterator并不是把集合元素本身传给了迭代变量,而是把集合元素的值传给了迭代变量,所以修改迭代变量的值对接元素本身没有任何影响。
所以我理解①处的b只是一个迭代变量,修改它并不会影响集合。接着是这段代码:
import java.util.*;
public class Test {
private String a;
public Test(String a){
this.a = a;
}
public String toString(){
return "["+a+"]";
}
public static void main(String[] args){
HashSet hs = new HashSet();
hs.add(new Test("java"));
hs.add(new Test("c++"));
hs.add(new Test("ruby"));
System.out.println(hs);
//取出第一个元素
Iterator it = hs.iterator();
Test first = (Test)it.next();
//为第一个元素的a实例变量赋值
first.a = "C#";
System.out.println(hs);
}
}
这是书上的代码,结果如下:
[[java], [c++], [ruby]]
[[C#], [c++], [ruby]]于是我的疑问就来了:这两段代码的区别无非是第一个用的String,第二个手动写了个类,修改的是类成员。为什么第二段代码用next()就能取出元素并修改。第一个不也是取出元素了吗,为啥修改了最后的结果又没有修改到集合呢?
于是我猜想,因为集合是保存的对象,而第一代码是修改的对象,第二个是修改的对象成员。是不是不能修改对象呢,只能修改对象成员呢?但是感觉这个猜想也不对,因为第一段代码书上说通过it.next()只是值传递,把值给了迭代变量,按照书上这段话理解,第一段代码的b和第二段代码的first只是迭代变量,修改它都不应该会对集合元素造成影响啊。为什么第二段代码又能修改了??
我晕了
求大神指点!谢谢!!Java集合
import java.util.*;
public class IteratorTest
{
public static void main(String[] args)
{
Collection books = new HashSet();
books.add(new String("Java EE"));
books.add(new String("IOS"));
books.add(new String("Android"));
System.out.println(books);
Iterator it = books.iterator();
String b = (String)it.next(); //①
b = "aaa";
System.out.println(books);
}
}
这段代码是我用书上的范例改了改,运行结果如下:
[Android, IOS, Java EE]
[Android, IOS, Java EE]对应的这段代码书上是这么讲解的:
当使用Iterator对集合元素进行迭代时,Iterator并不是把集合元素本身传给了迭代变量,而是把集合元素的值传给了迭代变量,所以修改迭代变量的值对接元素本身没有任何影响。
所以我理解①处的b只是一个迭代变量,修改它并不会影响集合。接着是这段代码:
import java.util.*;
public class Test {
private String a;
public Test(String a){
this.a = a;
}
public String toString(){
return "["+a+"]";
}
public static void main(String[] args){
HashSet hs = new HashSet();
hs.add(new Test("java"));
hs.add(new Test("c++"));
hs.add(new Test("ruby"));
System.out.println(hs);
//取出第一个元素
Iterator it = hs.iterator();
Test first = (Test)it.next();
//为第一个元素的a实例变量赋值
first.a = "C#";
System.out.println(hs);
}
}
这是书上的代码,结果如下:
[[java], [c++], [ruby]]
[[C#], [c++], [ruby]]于是我的疑问就来了:这两段代码的区别无非是第一个用的String,第二个手动写了个类,修改的是类成员。为什么第二段代码用next()就能取出元素并修改。第一个不也是取出元素了吗,为啥修改了最后的结果又没有修改到集合呢?
于是我猜想,因为集合是保存的对象,而第一代码是修改的对象,第二个是修改的对象成员。是不是不能修改对象呢,只能修改对象成员呢?但是感觉这个猜想也不对,因为第一段代码书上说通过it.next()只是值传递,把值给了迭代变量,按照书上这段话理解,第一段代码的b和第二段代码的first只是迭代变量,修改它都不应该会对集合元素造成影响啊。为什么第二段代码又能修改了??
我晕了
求大神指点!谢谢!!Java集合
这里传给b的是String型的值
那么这里的b应该是一个新的对象。//楼主可以做个实验试试,看看hashcode是不是一样的。
Test first = (Test)it.next();
这里应该传入的是地址值吧。
传入的是地址值,如果你只是对这个地址值进行修改的话,我估计也不影响原对象,
但是如果你对这个地址值上的值进行修改,那应该就不行了吧。个人感觉,有错请指出。。
String b = "aaa";创建了一个新的“aaa”对象,将使引用 b指向他,
执行完后,引用b表示了另一个对象,和原对象一点关系都没有
怎么可以证明
“当使用Iterator对集合元素进行迭代时,Iterator并不是把集合元素本身传给了迭代变量,而是把集合元素的值传给了迭代变量,所以修改迭代变量的值对接元素本身没有任何影响。”
而System.out.println(hs);
//取出第一个元素
Iterator it = hs.iterator();
Test first = (Test)it.next();
//为第一个元素的a实例变量赋值
first.a = "C#";
System.out.println(hs);
这段代码说明:
(Test)it.next(); 是一个引用,指向堆中的内存地址,因为执行完以下两句
Test first = (Test)it.next();
first.a = "C#";
对first的修改,表现到了集合中的对象
因此可以肯定it.next(); 返回的是一个对象引用
求大神详解啊!!!!
这样理解楼主在书中看到的那一句:通过迭代器遍历集合时,返回的的确是集合中的一个元素值,只不过这个值就是元素的引用(地址),基于#4楼的解释,改变引用不会对元素造成影响。而你的第二个例子并不是“改变值”,而是改变了“值”(引用)指向的那个对象的“状态”(此例中你是改变了一个属性),因此你的第二个例子并不恰当。
第二个例子应该改成这样:first.a = "C#";——> first = new Test("C#");
结果依然佐证了那句话想表达的意思。此外,lz看到的书中的这句话,把“Iterator并不是把集合元素本身传给了迭代变量”这句去掉,理解剩下的就比较清晰了。