for each循环变量赋值问题

对于普通类型来讲

 public void test() {
        List<String> strList = new ArrayList<String>();
        strList.add("乐视网");
        strList.add("财经网");
        strList.add("凤凰网");
        for(String str:strList){
            if("乐视网".equals(str)){
                str = "腾讯网";
            }
        }
        System.out.println(strList);
}

这段代码输出的结果是: [乐视网, 财经网, 凤凰网]
可见循环计数器只是一个中间变量,它仅仅保存了当前正在遍历的集合元素,因此对其赋值并不会改变集合元素本身。

但是,对于map、对象类型来讲

    public void test() {
    List<Map<String,Object>> stringList = new ArrayList<Map<String,Object>>();
        Map<String,Object> map = new HashMap<String, Object>();
        map.put("leshi", "乐视网");
        map.put("caijing", "财经网");
        map.put("fenghuang", "凤凰网");
        stringList.add(map);
        for(Map<String,Object> m:stringList){
            if("乐视网".equals(m.get("leshi"))){
                m.put("leshi", "乐视体育");
            }
        }
        System.out.println(stringList);
    }

这段代码输出的结果则为: [{fenghuang=凤凰网, caijing=财经网, leshi=乐视体育}]
显然原来的map的value被改变了。
这是为什么呢?

我也是小白,我觉得遍历第一段代码你没有add进去,没添加就没保存了,直接添加可能有问题,第二段明显put到对象当中了

String类型在Java中是引用类型。
举个例子,

String str1 = "one";
String str2 = str1;
str2 = "two";

上面三个式子,因为String是引用类型,执行前两句后,其实是相当于str1和str2两个变量同时指向同一个String类型,值为“one”。
但是str2 = “two”的意思,是str2重新被指向了一个新的变量String,值为“two”,而不是改变原来的String类型的值。
在foreach中也很好的表现了这点,str作为中间变量,遍历的同时和strList的每个遍历值同时指向同一个对象String。
但是你执行的str = "腾讯网";这个语句,只是改变了中间变量指向新的String,而不是修改旧String的值。
而在你的第二个代码片中,使用的是Map类型。Map是一种键值对形式存在的引用类型。
foreach中m作为中间变量,同时指向了遍历的Map,而你使用的是m.put()函数,就是使用了指向的那个Map的方法,put将value改变了,所以整个集合的value跟着改变了。

这是个人的浅显理解,其实关键在于你改变值的方式其实两个代码片是不同的。
一个是直接用=改变,一个用既有的Map内含的函数改变。String类型的=并不是和基本类型一样,是普通的改变赋值,而是重新创建了一个新的对象,新的值。

String这个类比较特殊,具有不变性,for循环时,strlist中的对象取出来,将值付给了str,从此str和strlist没有半毛钱关系了

没毛病,前面是把map去取到的值赋给str,str跟map里的值没关系了,后者则直接更改map的值,

....
Map 集合是键值对 存储 同样的key值 重复赋值会被覆盖的 就像你现在的结果一样

大兄弟你循环时只是把"腾讯网"赋值给str 就是这句 str = "腾讯网"| 注意是 str, 并不是Arraylist里面的元素。
**
List strList = new ArrayList();
strList.add("乐视网");
strList.add("财经网");
strList.add("凤凰网");
Integer add = null;
for (String str : strList) {
if ("乐视网".equals(str)) {
add = strList.indexOf(str);
}
}
strList.remove(add.intValue());
strList.add(add, "腾讯网");
System.out.println(strList);
**
你这样 就输出了。ArrayList不像map一样能根据key进行赋值,list可以添加或者移除元素,不存在赋值,上边的代码也是先移除后添加。注意别再循环里面操作list

你操作的是同一个对象 别以为放进List的map 就操作的不是 原始的map了
list只是存储了下你的map 两者没关联的

list 遍历中 你定义的是临时变量,它有单独的存储区,所以并没有改变原来list的值
map 底层采用数组+链表的数据结构,你两次的key相同,生成的hashcode值相同,会把数据存到前一个数据的链表中,最后输出的值就会改变
hashmap 详见http://blog.csdn.net/u012976158/article/details/53942284