2

I have two ArrayLists . I want just reuse the second arraylist (temporaryArrayList). Please notice my code . Hope you of course will understand what i want to make you know.

    ArrayList<ArrayList<String>> arrayListContainer = new ArrayList<>();
    ArrayList<String> temporaryArrayList = new ArrayList<>();

    temporaryArrayList.add("I");
    temporaryArrayList.add("you");
    temporaryArrayList.add("he");
    temporaryArrayList.add("she");
    temporaryArrayList.add("we");

    arrayListContainer.add(temporaryArrayList);

    temporaryArrayList.clear();

    temporaryArrayList.add("Rahim");
    temporaryArrayList.add("jon");
    temporaryArrayList.add("don");
    temporaryArrayList.add("shaila");

    arrayListContainer.add(temporaryArrayList);
    temporaryArrayList.clear();


    System.out.println(arrayListContainer.size());

The code is giving expected size of arrayListContainer but does not give expected result for

System.out.println(arrayListContainer.get(0).get(0));

How can I achieve this. Any kind of reply or suggestion will be accepted thankfully.

Sadhon
  • 674
  • 7
  • 11
  • What are you expecting `System.out.println(arrayListContainer.get(0).get(0));` to give you? – d512 Aug 26 '17 at 05:15
  • Why do you want to re-use the `temporaryArrayList`? As the answers point out, you are going to have to make a copy of it anyway. So there are not any savings, only more confusion. – Thilo Aug 26 '17 at 05:21
  • I need an arraylist of type arraylist for my project .. – Sadhon Aug 26 '17 at 05:32
  • See my answer - extract the creation of the temporary ArrayList to a method and call the method to create each ArrayList that you are adding to arrayListContainer. – Momus Aug 26 '17 at 05:45

6 Answers6

3

You're adding the same object and deleting it as well. In order to add different temp-lists to arrayListContainer you should create a copy:

change the lines that do:

arrayListContainer.add(temporaryArrayList);

to:

ArrayList<String> copy = new ArrayList<>(temporaryArrayList)
arrayListContainer.add(copy);

Another option, as Thilo suggests in a comment below, would be to create a new temporaryArrayList every time, this way you'll ensure adding different temp lists to arrayListContainer as well.

Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
2

You need to create a clone of the ArrayList when you add it, otherwise when you delete the contents you are erasing the contents of the actual list you just added. Cloning it will add a copy of the ArrayList instead of the original.

EDIT: Actually - based on Thilo's comment on the other answer - a better solution would be to extract the temporary ArrayList code to a method and call it:

 public static void main(String[] args){

    ArrayList<ArrayList<String>> arrayListContainer = new ArrayList<>();

    String[] a = {"I","you","he"};
    arrayListContainer.add(createArrayList(a));
    String[] b = {"Bob","Rahim","Betty"};
    arrayListContainer.add(createArrayList(b));

    System.out.println(arrayListContainer.size());
    System.out.println(arrayListContainer.get(0).get(0));
 }

 private static ArrayList<String> createArrayList(String[] arr) {
     ArrayList<String> temporaryArrayList= new ArrayList<>();
     for(String str : arr) {
         temporaryArrayList.add(str);
     }
     return temporaryArrayList;
 }
Momus
  • 394
  • 2
  • 13
2

Other Answers are correct. You are reusing your second ArrayList, just not in the fashion you intended.

You need to understand (a) references to objects, and (b) ArrayList is an object that is a container of references to other objects.

Let's look at the state during the execution of your code.

First instantiate an ArrayList with the default of ten slots. Will hold references to other ArrayList instances that hold references to String objects.

ArrayList< ArrayList< String > > arrayListContainer = new ArrayList<>();

enter image description here

ArrayList< String > temporaryArrayList = new ArrayList<>() ;

enter image description here

Instantiate String objects, adding a reference to each in a slot in our second list. Remember the list contains a reference to the String object, not the object itself.

temporaryArrayList.add( "I" ) ;
temporaryArrayList.add( "you" ) ;
temporaryArrayList.add( "he" ) ;
temporaryArrayList.add( "she" ) ;
temporaryArrayList.add( "we" ) ;

enter image description here

Add a reference to the second list to the first slot of the first list.

arrayListContainer.add(temporaryArrayList) ;

enter image description here

Remove all the references to the String objects with pronouns by calling clear(). Those String objects actually exist in memory for a while, becoming candidates for garbage collection since they are not referenced by any other objects. So we show them as gone in this diagram, but actually they may be floating around in memory for a while longer.

temporaryArrayList.clear() ;

enter image description here

Instantiate some new String objects. Put a reference to each in the slots of our second list.

temporaryArrayList.add( "Rahim" ) ;
temporaryArrayList.add( "jon" ) ;
temporaryArrayList.add( "don" ) ;
temporaryArrayList.add( "shaila" ) ;

enter image description here

Here is where your misunderstanding appears. You apparently wanted to keep the pronouns and add some proper names alongside them. But the first list does not hold references to String objects, it holds a reference to an ArrayList of String objects. So we end up two references to the same ArrayList object containing references to proper name strings. The old pronoun strings may or may not be still floating around in memory, but we can no longer reach them so we think of them as gone.

arrayListContainer.add( temporaryArrayList ) ;

enter image description here

Next you clear the one-and-only list of strings. So now the first ArrayList hold two references to the same now-empty second ArrayList.

temporaryArrayList.clear() ;

enter image description here

You end up with one list of two elements where each element is pointing to the same empty "temp" list.

If you wanted to accumulate the strings in the first list, redefine that first list as an ArrayList of String rather than of ArrayList<String>. So, instead of this:

ArrayList< ArrayList< String > > arrayListContainer = new ArrayList<>() ;
ArrayList< String > temporaryArrayList = new ArrayList<>() ;
…
arrayListContainer.add( temporaryArrayList ) ;

…this, changing add to addAll:

ArrayList< String > arrayListContainer = new ArrayList<>() ;
ArrayList< String > temporaryArrayList = new ArrayList<>() ;
…
arrayListContainer.addAll( temporaryArrayList ) ;  // Call `addAll` to add the elements of one collection to another collection.

Tip: Use interfaces where possible.

Generally best to specify more generic interfaces rather than concrete classes, so you can more easily switch out concrete classes; so you could use List: List< List<String> >.

List<List<String>> listContainer = new ArrayList<>();
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
2
    ArrayList<ArrayList<String>> arrayListContainer = new ArrayList<>();
    ArrayList<String> temporaryArrayList = new ArrayList<>();

    temporaryArrayList.add("I");
    temporaryArrayList.add("you");
    temporaryArrayList.add("he");
    temporaryArrayList.add("she");
    temporaryArrayList.add("we");

    arrayListContainer.add(new ArrayList<>(temporaryArrayList));

   temporaryArrayList.clear();

    temporaryArrayList.add("Rahim");
    temporaryArrayList.add("jon");
    temporaryArrayList.add("don");
    temporaryArrayList.add("shaila");

    arrayListContainer.add(new ArrayList<>(temporaryArrayList));
    temporaryArrayList.clear();


    System.out.println(arrayListContainer.get(0).get(0));

This is just another natural way of cloning the object :)

Rahul Raj
  • 3,197
  • 5
  • 35
  • 55
1

You can't reuse it in the way you want. Your ArrayList<ArrayList<String>> contains references to objects (in this case, references to ArrayList<String>). If you say

arrayListContainer.add(temporaryArrayList);

and later,

arrayListContainer.add(temporaryArrayList);

without assigning a new value to temporaryArrayList in between, your arrayListContainer will have two references to the same object. temporaryArrayList is a reference to an object, and it doesn't change even if the contents of the object change (unless you reassign a whole new object to it).

You'll need to create a new object.

ajb
  • 31,309
  • 3
  • 58
  • 84
1

In your case you don't need an array list of array list, just make it an array list of string array:

ArrayList<String[]> arrayContainer = new ArrayList<>();

When done adding the strings, call:

arrayContainer.add(temporaryArrayList.toArray(new String[temporaryArrayList.size()]));

That way you can safely reuse the temp array list.

Antony Ng
  • 767
  • 8
  • 16