Joe520Kay
2017-01-17 08:52
采纳率: 0%
浏览 3.5k

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被改变了。
这是为什么呢?

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

8条回答 默认 最新

  • upgraded123 2017-01-17 09:23

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

    评论
    解决 无用
    打赏 举报
  • Book1346 2017-01-17 09:31

    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类型的=并不是和基本类型一样,是普通的改变赋值,而是重新创建了一个新的对象,新的值。

    评论
    解决 无用
    打赏 举报
  • 68号小喇叭 2017-01-17 09:40

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

    评论
    解决 无用
    打赏 举报
  • alan_waker 2017-01-17 10:05

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

    评论
    解决 无用
    打赏 举报
  • 死神小队 2017-01-17 10:23

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

    评论
    解决 无用
    打赏 举报
  • Amin已经存在了 2017-01-17 10:26

    大兄弟你循环时只是把"腾讯网"赋值给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

    评论
    解决 无用
    打赏 举报
  • 死神小队 2017-01-17 10:27

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

    评论
    解决 无用
    打赏 举报
  • 强化脑细胞 2017-01-17 11:03

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

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题