views:

172

answers:

2

I am trying to add an object to an arraylist but when I view the results of the array list, it keeps adding the same object over and over to the arraylist. I was wondering what the correct way to implement this would be.

    public static ArrayList<Contact> parseContacts(String responseData) {
    ArrayList<Contact> Contacts = new ArrayList<Contact>();
    try {

        JSONArray jsonContacts = new JSONArray(responseData);
        if (!jsonContacts.isNull(0)) {
            for (int i = 0; i < jsonContacts.length(); i++) {
                Contacts.add(new Contact(jsonContacts.getJSONObject(i)));
            }

        }

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

    }

    return Contacts;
}

I have double checked my JSONArray data and made sure they are not duplicates. It seems to keep adding the first object over and over.

+2  A: 

Some quick tips:

  • Consider following naming convention. Variable names starts with lowercase.
  • Effective Java 2nd Edition, Item 65: Don't ignore exceptions
  • Effective Java 2nd Edition, Item 52: Refer to objects by their interfaces

Having said that, you can add to an ArrayList the same way you add to ANY List: you can add(E) a single element or addAll an entire Collection<? extends E> to the end of the list. There are also overloads that takes an index if you want to add element(s) to a more specific location.


On aliasing

Always remember that objects are reference types, and references can be aliased. Unless you understand what this means, some behaviors may surprise you.

This snippet shows an example of:

  • Creating a List of 3 AtomicReference instances that all refers to the same AtomicInteger.
  • When the AtomicInteger is incremented, all AtomicReference sees this effect
  • One AtomicReference is then set to refer to a second AtomicInteger

(There is nothing specific about concurrency in this example)

    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]

Note that even though a new AtomicReference was used for List.add every time (meaning 3 different AtomicReference objects are created total), they were still referring to the same AtomicInteger. This sorts of aliasing may be the source of your problem.

polygenelubricants
+1  A: 

There is either a problem with the responseData string or the constructor.

If the class receives a response Data object that looks like the following

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

Then your Contact class should look like

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
}

There should be no reason based on your logic to have the same record show up twice. Make sure your JSON string has the correct format coming in. I would suggest adding more System.out or Log4j calls in the application to determine every step. Worst case step through the application with a debug session.

PS - I built you app by adding the above code and it worked fine. So you have the grasp on adding the elements to the ArrayList properly. Could you also show how you print the array back out? Maybe the issue is there.

Sean