容器类仅能持有对象引用(指向对象的指针) 而不是将对象信息copy一份至数列某位置。

来源:互联网 发布:安娜贝尔2 知乎 编辑:程序博客网 时间:2024/05/16 08:13

最近在做一个项目里,给ArrayList 赋值发现结果不正常。仔细想了一下然来是没有深入理解 “容器类仅能持有对象引用(指向对象的指针)”  这句话。
下面来看一下示例程序:

import java.util.ArrayList;import java.util.HashMap;import java.util.Map;public class MapList {public static void main(String []args){ArrayList <Map<String,String>> mapList=new ArrayList <Map<String,String> >();Map<String ,String> map=new HashMap<String,String>();for(int i=0;i<5;i++){map.put("key","value"+i);mapList.add(map);}System.out.println("mapList.size:"+mapList.size());System.out.println("mapList:"+mapList);System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>");ArrayList <Map<String,String>> mapList1=new ArrayList <Map<String,String> >();for(int i=0;i<5;i++){Map<String ,String> map1=new HashMap<String,String>();map1.put("key","value"+i);mapList1.add(map1);}System.out.println("mapList1:"+mapList1);}}

打印结果为:
mapList.size:5mapList:[{key=value4}, {key=value4}, {key=value4}, {key=value4}, {key=value4}]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mapList1:[{key=value0}, {key=value1}, {key=value2}, {key=value3}, {key=value4}]
为什么第一条打印的是:[{key=value4}, {key=value4}, {key=value4}, {key=value4}, {key=value4}]。
因为map 只new 了一次,且在循环外。并且collection 是持有对象的引用。
Map<String ,String> map=new HashMap<String,String>();for(int i=0;i<5;i++){map.put("key","value"+i);mapList.add(map);}
所以打印出来肯定是一样的都是:[{key=value4}, {key=value4}, {key=value4}, {key=value4}, {key=value4}]。
效果如图所示:


而mapList 打印出来结果为:mapList1:[{key=value0}, {key=value1}, {key=value2}, {key=value3}, {key=value4}]。
如下图所示:



在我另一篇转载博客了讲了( link 为: http://blog.csdn.net/clam_clam/article/details/6645021 ) 
1、容器类和Array的区别、择取
      *     容器类仅能持有对象引用(指向对象的指针),而不是将对象信息copy一份至数列某位置。
      *     一旦将对象置入容器内,便损失了该对象的型别信息

但今天一开始还出错所以看书固然重要 ,实践更重要呀。

没看书的话不可能一出错就意识到问题所在,也要经过实践才能强化知识。

System.out.println("mapList1:"+mapList1);System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>");ArrayList <Integer> list3=new ArrayList <Integer> ();Integer intvar=new Integer(0);for(int i=0;i<5;i++){intvar=i;list3.add(intvar);}System.out.println(list3);System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>");ArrayList <User> list4=new ArrayList <User> ();User user=new User();for(int i=0;i<5;i++){user.setName("name"+i);list4.add(user);}System.out.println(list4);

结果为:
[0, 1, 2, 3, 4]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[User [name=name4], User [name=name4], User [name=name4], User [name=name4], User [name=name4]]。
为什么事 [0,1,2,3,4]因为:intvar=i; 会自动装箱,new 一个空间。

而User [name=name4], User [name=name4], User [name=name4], 不会。没有在for 循环里重新开辟空间所以都指向同一个空间。
2. 对象类型数组也是持有引用
看下面例子:

class Obj{String name;Obj(String name){this.name=name;}void setName(String name){this.name=name;}@Overridepublic String toString() {return "Obj["+this.name+"]";//return super.toString();}}public class FS {     public static void main(String[] args){             Obj[] arr=new Obj[5];           Obj obj=new Obj("computer");           for(int i=0;i<5;i++){             arr[i]=obj;           }           System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");           for(int i=0;i<5;i++){             System.out.print(arr[i]);           }           System.out.println("");           obj.setName("info");           System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");           for(int i=0;i<5;i++){             System.out.print(arr[i]);           }           System.out.println("");           }  }
运行结果为:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Obj[computer]Obj[computer]Obj[computer]Obj[computer]Obj[computer]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Obj[info]Obj[info]Obj[info]Obj[info]Obj[info]
改变obj 后arr 数组都改变了,所以数组拥有的是obj 对象的引用。


原创粉丝点击