List.add()方法中的陷阱

今天在做微信项目时,发现了一个奇怪的问题,代码如下:

 JSONObject j = new JSONObject();
        List<JSONObject> list = new ArrayList<JSONObject>();

        j.put("author", "1yuqiaotech");
        j.put("title", "1测试标题");
        //在图文消息页面点击“阅读原文”后的页面
        j.put("content", "1测试asiuninasd");
        j.put("digest", "1digest");
        System.out.println("json1:" + j);
        list.add(j);

        j.put("author", "2yuqiaotech");
        j.put("title", "2测试标题");
        //图文消息页面的内容,支持HTML标签
         j.put("content", "2测试asiuninasd");
        j.put("digest", "2digest");
        System.out.println("json1:" + j);
        list.add(j);

        System.out.println("list(0):" + list.get(0));
        System.out.println("list(1):" + list.get(1));

这段代码的目的是将两个JSON格式的内容放在list里,首先new一个JSONObject对象,将第一个内容put到里面,然后将这个JSONObject添加到list中;接着为这个JSONObject重新put值,那么之前的值将会被覆盖掉,新的内容就会被put到该JSONObject中,然后将这个JSONObject添加到list中;想象中此时list里应该有两个不同的JSON对象了,打印结果:

奇怪,list中两个都是json2的内容,json1的内容不见了。

针对这个问题,做一下测试:

首先用list保存基础类型对象变量:

        List<Integer> intList = new ArrayList<Integer>();
        int i = 1;
        intList.add(i);
        System.out.println(intList);
        i = 2;
        intList.add(i);
        System.out.println(intList);

,发现打印结果是没有问题的。

仍然用上面的JSONObject:

        JSONObject j = new JSONObject();
        List<JSONObject> list = new ArrayList<JSONObject>();

        j.put("author", "1yuqiaotech");
        j.put("title", "1测试标题");
        //在图文消息页面点击“阅读原文”后的页面
        j.put("content", "1测试asiuninasd");
        j.put("digest", "1digest");
        System.out.println("json1:" + j);

        list.add(j);
        System.out.println("list:" + list);

        j.put("title", "2测试标题");

        System.out.println("list:" + list);

打印结果:

为什么会这样呢?

这个问题要从Java存储结构来看了,对于基础类型数据,直接存储在栈中,而当像list添加new的对象时,只是将对象的引用传给放在了list中,当该引用指向的对象发生变化时,对应的list里的内容也就跟着发生变化了。

这种情况下就必须用两个不同的JSONObject对象来分别存储了。

也是我粗心大意了啊。

时间: 2024-08-28 10:02:03

List.add()方法中的陷阱的相关文章

Android 系统menu中add方法中参数的含义!!!

menu.add的方法中的参数: 1.int类型的group ID参数,代表的是组概念,你可以将几个菜单项归为一组,以便更好的以组的方式管理你的菜单按钮.可以用到的方法有: removeGroup(id) setGroupCheckable(id, checkable, exclusive) setGroupEnabled(id,boolean enabled) setGroupVisible(id,visible) 2.int类型的item ID参数,代表的是项目编号.这个参数非常重要,一个i

TreeSet有趣问题之add方法原理

先看如下代码 class Worker implements Comparable<Worker> { private int age; private String name; public Worker(int age, String name) { this.setAge(age); this.setName(name); } @Override public int hashCode() { final int prime = 31; int result = 1; result =

注意DefaultMutableTreeNode的add方法

由于本人在写一个小工具,用到了swing的JTree组件,节点实现类为DefaultMutableTreeNode,却遇到了一个有点想不通的问题,后来看源代码找到了答案,谨此记录一下.下面是一个对此问题设计的一段代码: public static void main(String[] args) { DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");//根节点 DefaultMutableTreeNode

TreeSet.add()方法一细节

最近在一次使用TreeSet.add()方法中遇到了一个很迷惑的问题:往一个TreeSet集合中添加几个对象的时候发现有些没有添加进去,一开始是怀疑hashcode与equals的问题,因为Set集合是不允许添加两个相同对象的,但经查检确认没有问题,几经测试发现是传入的Comporator对象引起的(即使用的是TreeSet(Comparator<? super E> comparator)构造方法),当其compare()方法返回0时,只能添加进一个对象,只要当前添加的对象与集合中的任意一个

java List.subList方法中的超级大陷阱

ArrayList 中 subList 的基本用法: subList(fromIndex:int,toIndex:int):List<E> 返回从fromIndex到toindex-1 的 子列表 在使用集合中,可能常常需要取集合中的某一部分子集来进行一下操作,于是subList这个方法就映入我们的眼帘,毫不犹豫地使用. 例如以下代码: public static void main(final String[] args) { List<Object> lists = new A

JavaScript中Add方法dictionary

Add 方法 (Dictionary) 向 Dictionary 对象中添加一个主键条目对. object.Add (key, item) 参数 object 必选项.总是一个 Dictionary 对象的名称. key 必选项.与被添加的 item 相关联的 key. item 必选项.与被添加的 key 相关联的 item. 说明 如果 key 已经存在,那么将导致一个错误.http://rl.82676666.com 下面这个例子说明了 Add 方法的用法. var d; d = new

JavaScript中Add方法folders

Add 方法 (Folders) 向 Folders 集合中添加新的 Folder . object.Add (folderName) 参数 object 必选项. 应为 Folders 集合的名称. folderName 必选项. 要添加的新 Folder 的名称. 说明 下面的例子说明了使用 Add 方法创建新文件夹的方法. function AddNewFolder(path,folderName) { var fso, f, fc, nf; fso = new ActiveXObhttp

在使用add()方法添加组件到容器时,必须指定将其放置在哪个区域中

BorderLayout是Window.Frame和Dialog的默认布局管理器,其将容器分成North.South.East.West和Center 5个区域,每个区域只能放置一个组件. 在使用add()方法添加组件到容器时,必须指定将其放置在哪个区域中. 使用BorderLayout时,如果容器大小发生变换,组件的相对位置不变. 1 package TomAwt; 2 3 4 import java.applet.Applet; 5 import java.awt.*; 6 public c

编写高质量代码改善C#程序的157个建议——建议38:小心闭包中的陷阱

建议38:小心闭包中的陷阱 先看一下下面的代码,设想一下输出的是什么? static void Main(string[] args) { List<Action> lists = new List<Action>(); for (int i = 0; i < 5; i++) { Action t = () => { Console.WriteLine(i.ToString()); }; lists.Add(t); } foreach (Action t in list