2

I have created a custom class called Song which contains 3 String variables, an int variable and an ArrayList of String items.

Now I have the correct getters and setters for all of the variables and such, however the issue is that, when I assign something to the ArrayList variable and try to access it later, it throws an IndexOutOfBounds error because the size of it is 0. Below is the code in question.

Is it possible that I'm not assigning the variable correctly or possibly its memory location is being affected by clearing it?

Important note: I am able to access and print the values of the other variables but the ArrayList variable is the only one that fails.


SongClass.java

@Parcel
public class SongClass {
    //Other variables defined here
    ArrayList <String> verses;

    public Song() { /*Required empty bean constructor*/ }

    public Song(String var1, String var2, String var3, int var4, ArrayList<String> verses) 
    {
        this.var1= var1;
        this.var2= var2;
        this.var3= var3;
        this.var4= var4;
        this.verses = verses;
    }

    //Getters and Setters below

SongReader.java

//Use to store a collection of Song objects (multiple songs)
private ArrayList<Song> songs = new ArrayList<>(10);

//This array will be assigned to the Song object -> verses
private ArrayList<String> verses = new ArrayList<>(10); 
//Other vars to be assigned to song object (String, String, String, int)

...

songs.add(new Song(String var1, String var2, String var3, int var4, verses);

//Important note: I clear the verses `ArrayList` after assigning it to songs. Could this possibly erase it from songs?
verses.clear();

SongDisplay.java

ArrayList<Songs> songs = Parcels.unwrap(intent.getParcelableExtra("Extras"));

...

for (int i = 1; i <= songs.get(0).size(); ++i)
{
    TextView textView = new TextView(this);
    ...
    //Error is thrown here
    textView.setText(songs.get(0).getVerses().get(i-1);
    ...
 }
Keno
  • 2,018
  • 1
  • 16
  • 26

5 Answers5

2

Your comment is correct. Since the ArrayList you pass to song and the ArrayList you call clear() on are the same object they both get cleared.

If you need to clear the ArrayList pass a new ArrayList into the Song constructor that copies the contents of verses.

songs.add(new Song(String var1, String var2, String var3, int var4, new ArrayList(verses));

Also, note that arrays and lists in java start at index 0 so you should fix the for loop too.

// hard coding songs.get(0) could lead to issues as well but at least fix the index i
for (int i = 0; i < songs.get(0).size(); i++)
{
    TextView textView = new TextView(this);
    ...
    //Error is thrown here
    textView.setText(songs.get(0).getVerses().get(i);
    ...
 }
George Mulligan
  • 11,813
  • 6
  • 37
  • 50
  • I knew it :D I'm still somewhat new to Android development so I wasn't sure if the clear method would affect it even if it was passed to another class. – Keno Apr 11 '16 at 17:18
  • Oh and regarding your latest edit, I actually had `get(i-1)` instead of `get(i)`, updating question. – Keno Apr 11 '16 at 17:21
  • Got it. However, it is much clearer to start i at 0 instead of having `i - 1`. Others will be confused if you do that when they read your code and you might even end up confusing yourself later ;). – George Mulligan Apr 11 '16 at 17:23
  • 1
    True. I may edit my actual code to incorporate that instead. – Keno Apr 11 '16 at 17:24
1

The problem is that you are calling clear in you ArrayList reference. when you call songs.add and pass verses to it and clear it, you are cleaning the reference.

You have to instantiate the array that you are passing to songs.add like below:

ArrayList<String> auxVerses = new ArrayList<>(verses);

songs.add(new Song(String var1, String var2, String var3, int var4, auxVerses);
Lucas Ferraz
  • 4,112
  • 2
  • 18
  • 23
1

Because your declared verses ArrayList is empty when your statement

private ArrayList<String> verses = new ArrayList<>(10); 

By new ArrayList<>(10); you are NOT creating a new ArrayList with 10 elements rather than just define an initial capacity. So your verses is empty with verses.size() is 0.

Even if you dont call verses.clear(); still its empty.

Another example to make it clear

List<String> list = new ArrayList<String>(10);
System.out.println(list.size());// print '0'
list.add("A");
System.out.println(list.size());// print '1'
list.clear();
System.out.println(list.size());// print '0'
rev_dihazum
  • 818
  • 1
  • 9
  • 19
0
verses.clear();  

Because of this line of code you are getting array list size 0.

Muhammad Umair
  • 583
  • 11
  • 32
0

Keep in mind that calling private ArrayList<String> verses = new ArrayList<>(10); does not create an ArrayList with 10 new "empty" items. It simply sets the maximum capacity of the List. So if you try to access any of the items, you won't get a null value or an empty value of any kind, because you haven't actually added anything to the list. You've just ensured it has memory set aside for 10 items. So calling ArrayList.size() on this List will rightly report back zero items.

NoChinDeluxe
  • 3,446
  • 1
  • 16
  • 29
  • 2
    Yes I'm aware of this. I've made sure to add each one, but thanks for the reminder. – Keno Apr 11 '16 at 17:19