-1

I have seen this 2d Arraylist Question multiple times on SO, but don't understand why this doesn't work for my Language App.

I have an arraylist (called stage1) containing multiple arraylists (each is called entry) The System.out.println("In switch: this is entry" + entry); displays the database values correctly so I am sure that the query string elsewhere is correct (e.g. [In switch: this is entry[water, aqua, C:\Users\Username\Documents\NetBeansProjects\LanguageApp\src\Images\Categories\Food images\water.png])

But when I add entry to stage 1 and try to access it via stage1.get(0).get(0) I get the error "Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0" which is why I tested if stage1 is empty. The other trace statement confirms that stage1 is null even after entries are added.

   ArrayList<List<String>> stage1 = new ArrayList<>();

    ArrayList<String> entry = new ArrayList<>();
    int count = 0;

    //words is an Observable List of all words relating to a specific category and langage 
    for (Words k : words) {

        String eng = k.getEnglishWord();
        String trans = "";

        switch (lang) {

            case "spanish":
                trans = k.getSpanishWord();
                break;

            case "french":
                trans = k.getFrenchWord();
                break;

            case "german":
                trans = k.getGermanWord();
                break;

        }

        String pic = k.getPicture();


        entry.add(eng);
        entry.add(trans);
        entry.add(pic);

       System.out.println("This is entry" + entry);
       stage1.add(entry);
       entry.clear();


    if(stage1.size()!=0){  System.out.println("Stage1 " + stage1.get(0).get(0));
    }

    else {System.out.println("IT IS NULL");}     
}
Sbee
  • 37
  • 5
  • 3
    `entry.clear();` <- You are clearing your List entry at the end of every loop. Therefor it will have a size of 0. Also note that you are only creating one List that you add multiple times to your stage1 List. See Also: https://stackoverflow.com/questions/19843506/why-does-my-arraylist-contain-n-copies-of-the-last-item-added-to-the-list – OH GOD SPIDERS Oct 06 '17 at 09:58
  • 1
    Condition doesn't make sense: `if(stage1.size()==0)` – Robby Cornelissen Oct 06 '17 at 09:59
  • 1
    Bring the declaration of entry _inside_ the for loop. Then you add every time a new list object to stage1 instead of the same object over and over. Now your stage1 has n times the same cleared list object. – Joop Eggen Oct 06 '17 at 10:02
  • @OH GOD SPIDERS - `stage1.add(entry);` is *before* `entry.clear();` and entry needs to be temporary like that, and be cleared for every loop. – Sbee Oct 06 '17 at 10:03
  • 2
    @Sbee You don't understand and obviously did not read the the question i linked. Java does not automatically copy lists when you add them to other lists. So it doesn't matter if it is added before you call clear and it will still clear the list you just added. And again: You are adding the same list again and again instead of adding multiple list. – OH GOD SPIDERS Oct 06 '17 at 10:04
  • 1
    An ArrayList is a _reference_: after adding entry to stage1, clearing or changing entry will change the object in the list. – Joop Eggen Oct 06 '17 at 10:05
  • @Joop Eggen I moved the "entry" ArrayList declaration inside of the for loop- it worked and now I see why...thank you!! – Sbee Oct 06 '17 at 10:17

2 Answers2

3

You are using single object at each time that's why it gives index out of bounds exception

Just place your arraylist into the for loop

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

   for (int i = 0; i < 5; i++) {

      //put you code here




        ArrayList<String> entry = new ArrayList<String>();
        entry.add("sd");
        entry.add("sd");
        entry.add("sd");

       System.out.println("This is entry" + entry);
       stage1.add(entry);
       //entry.clear();


    if(stage1.size()==0){  System.out.println("Stage1 " + stage1.get(0).get(0));
    }

    else {System.out.println("IT IS NULL");}     
}

This will give's you desired output.

Vishal Kawade
  • 449
  • 6
  • 20
  • 1
    That should work , when the entry arrayList is inside the loop. also see that inserting entry to stage1 indeed increase the size of stage1 but clearing the array just remove all the references to the entry data. – Barak michaeli Oct 06 '17 at 10:24
2

Every object in Java are reference Object. When you pass an object trought parameters of function, you pass the reference. If you modify the object inside or outside the method you will modify the object in and or out of the function.

I suggest you to take a look to it to clear your mind about all this.

Is Java "pass-by-reference" or "pass-by-value"?

Now, to solve your problem, you can reinstanciate you entre with entry = new ArrayList(); and the begiining of each loop and remove the entry.clear();.

ArrayList<List<String>> stage1 = new ArrayList<>();

ArrayList<String> entry = null;
int count = 0;

//words is an Observable List of all words relating to a specific category and langage 
for (Words k : words) {
    entry = new ArrayList<>();
    String eng = k.getEnglishWord();
    String trans = "";

    switch (lang) {

        case "spanish":
            trans = k.getSpanishWord();
            break;

        case "french":
            trans = k.getFrenchWord();
            break;

        case "german":
            trans = k.getGermanWord();
            break;

    }

    String pic = k.getPicture();


    entry.add(eng);
    entry.add(trans);
    entry.add(pic);

   System.out.println("This is entry" + entry);
   stage1.add(entry);
   //entry.clear();


    if(stage1.size()!=0){  System.out.println("Stage1 " + stage1.get(0).get(0));
    }

    else {System.out.println("IT IS NULL");}     
}
DamienB
  • 419
  • 1
  • 6
  • 20