【问题标题】:Correct way to add objects to an ArrayList将对象添加到 ArrayList 的正确方法
【发布时间】:2010-08-19 23:40:11
【问题描述】:

我正在尝试将一个对象添加到数组列表中,但是当我查看数组列表的结果时,它会不断将相同的对象一遍又一遍地添加到数组列表中。我想知道实现它的正确方法是什么。

    public static ArrayList<Person> parsePeople(String responseData) {
    ArrayList<Person> People = new ArrayList<Person>();
    try {

        JSONArray jsonPeople = new JSONArray(responseData);
        if (!jsonPeople.isNull(0)) {
            for (int i = 0; i < jsonPeople.length(); i++) {
                People.add(new Person(jsonPeople.getJSONObject(i)));
            }

        }

    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (Exception e) {

    }

    return People;
}

我已经仔细检查了我的 JSONArray 数据并确保它们没有重复。它似乎一直在一遍又一遍地添加第一个对象。

【问题讨论】:

  • 一切对我来说都是正确的,只要将项目添加到您的列表中。只是出于好奇,您能否提供您的联系人类的代码?取决于此,以及 getJSONObject 是如何实现的,我知道它是如何做你所描述的。
  • 永远不要默默地捕捉到最抽象的异常。绝不。并在发布或显示其他人之前删除那些“// TODO 自动生成的捕获块”cmets,签入代码。禁用生成。
  • @user unknown:虽然你是对的,但我认为不值得对这个问题投反对票。恕我直言,它非常清晰有用。
  • @StriplingWarrior:不确定发布此内容的最佳方式,因为它对于评论而不是答案来说太大了。联系人类可以在这里找到:pastebin.com/3qSHCii1
  • 一些用户通常会在他们的原始问题中附加一个“更新”部分,但 pastebin 对我来说很好。根据 Contact 类的代码,我很确定问题不在那里。由于您已经仔细检查了输入,我不得不认为您以某种方式错误地检查了输出。您是否尝试过为此方法编写单元测试?如果有,它是什么样子的?

标签: java android android-activity performance arraylist


【解决方案1】:

一些快速提示:

  • 考虑关注naming convention。变量名以小写字母开头。
  • 有效的 Java 第 2 版,第 65 条:不要忽略异常
  • Effective Java 2nd Edition,Item 52:通过接口引用对象

话虽如此,你可以 addArrayList 就像你 addANY List:你可以 add(E) 单个元素或 addAll 一个整个Collection&lt;? extends E&gt; 到列表末尾。如果您想将元素添加到更具体的位置,也有需要索引的重载。


关于别名

永远记住对象是引用类型,引用可以有别名。除非您理解这意味着什么,否则某些行为可能会让您感到惊讶。

这个 sn-p 显示了一个示例:

  • 创建一个 List 的 3 个 AtomicReference 实例,它们都引用相同的 AtomicInteger
  • AtomicInteger 增加时,所有AtomicReference 都会看到这种效果
  • 然后将一个AtomicReference 设置为引用第二个AtomicInteger

(在这个例子中没有关于并发的具体内容)

    import java.util.concurrent.atomic.*;
    //...

    List<AtomicReference<AtomicInteger>> refs =
        new ArrayList<AtomicReference<AtomicInteger>>();        
    AtomicInteger counter = new AtomicInteger();

    for (int i = 0; i < 3; i++) {
        refs.add(new AtomicReference<AtomicInteger>(counter));
    }

    // we now have 3 AtomicReference,
    // but only 1 AtomicInteger

    System.out.println(refs);   // [0, 0, 0]
    counter.incrementAndGet();
    System.out.println(refs);   // [1, 1, 1]

    refs.get(1).set(new AtomicInteger(9));
    System.out.println(refs);   // [1, 9, 1]

    // we still have only 3 AtomicReference,
    // but we've also created a second AtomicInteger

    counter.incrementAndGet();
    System.out.println(refs);   // [2, 9, 2]

请注意,即使 List.add 每次都使用 new AtomicReference(意味着总共创建了 3 个不同的 AtomicReference 对象),它们仍然指的是同一个 AtomicInteger。这种别名可能是您的问题的根源。

【讨论】:

    【解决方案2】:

    responseData 字符串或构造函数有问题。

    如果类接收到如下所示的响应数据对象

    String responseData = 
    "[{ 
    \"first_name\" : \"fred\" , 
    \"last_name\" : \"Nobody\"  
    }, 
    { 
    \"first_name\" : \"John\" , 
    \"last_name\" : \"Somebody\"  
    }]";
    

    那么你的 Contact 类应该是这样的

    public class Contact {
        String fname;
        String lname;
    
        public Contact(JSONObject obj){
            System.out.println(obj);
            try {
                fname = (String)obj.get("first_name");
                lname = (String)obj.get("last_name");
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    //get and set methods
    }
    

    根据您的逻辑,应该没有理由让同一记录出现两次。确保您的 JSON 字符串具有正确的格式。我建议在应用程序中添加更多 System.out 或 Log4j 调用以确定每个步骤。最坏的情况是通过调试会话逐步完成应用程序。

    PS - 我通过添加上述代码为您构建了应用程序,它运行良好。因此,您可以正确地将元素添加到 ArrayList 中。您能否还展示如何将数组打印回来?也许问题就在那里。

    【讨论】:

    • 我猜这些字段在 People 类的 OPs 版本中是静态的。
    【解决方案3】:

    你不觉得

    Person.add(new Person(jsonPeople.getJSONObject(i)));
    

    应该像

    People.add(new Person(jsonPeople.getJSONObject(i)));
    

    我不知道你最初是如何编译文件的,除非你有一个名为 add(Person p) 的静态方法和一个在 Person 类中接受 Person(JSONObject j) 的构造函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-12
      • 1970-01-01
      • 2015-05-24
      • 1970-01-01
      • 2010-11-30
      • 1970-01-01
      • 2011-12-24
      相关资源
      最近更新 更多