Practice pieces


Packages

This practice piece is all about ArrayLists. You'll need to read all the docs for ArrayList to work through it.


Hints:

First thing to do is find the ArrayLists docs. The class' full name is java.util.ArrayList. Track it down in the API and read all of its methods. Get good and familiar with the methods for working with it.


Then, as ever, start simple:

1) A Alice class with nothing but a main and a constructor that "Hello World"s. Remember to import java.util.*.


2) Make an ArrayList in your Alice constructor. Now you have two choices. You can either deal with storing generic Objects in the ArrayList...

ArrayList arrayList = new ArrayList();

Or, better, you can define the stored type, thus:

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

Note the significant difference from setting up an array. This is not an array, it is a single object containing an array, and is set up appropriately.


3) For loop from 0 to 99. In this, use an if-else statement to add the right word to the ArrayList. See the docs for how to add objects. Remember, Strings are objects, though made in an unusual way.

String stringObject = "Tweedledum";


4) Add another looping structure below this. Get each String out of the ArrayList in turn. Check which option it is equal to. Remember, there is a special way of checking whether a String object is equal to a value:

if (stringObject.equals("Tweedledum")) {

where this is true, use the ArrayList's remove method to delete the object.


5) Test your code works.


Now, there is a significant issue with (4), but which significant issue depends on what kind of a loop you are using.

If you use a standard for-loop:

for (int i = 0; i < arrayList.size(); i++) {

   if (arrayList.get(i).equals("Tweedledum")) {
      arrayList.remove(arrayList.get(i));
   }

}

the code will run, but won't do the job. You'll still end up with some Tweedledums. Why do you think this is? Think though what is happening to the index variable of your loop and the position of the remaining objects when you remove an object from the underlying array.

The worse problem comes if you use a for-each loop:

for (String person: arrayList) {

   if (person.equals("Tweedledum")) {
      arrayList.remove(person);
   }

}

(we haven't used these much, but they're worth revisiting: see the materials on loops). This will compile, but it will throw a horrible exception when it runs called a ConcurrentModificationException. This means that you are trying to alter the size of an object that the system is currently using. For-each loops rely on the size of the collection staying the same, as there's no size check in the declaration that is visited anew each iteration as there is in the standard for-loop.

So, how might we get around these issues?

For the standard for-loop, what do you think the solution is? Remember, there's nothing to stop you messing around with index variables inside your loop, it's just generally frowned upon in most circumstances.

For the for-each loop, remember from the docs that one thing you can do with an ArrayList is copy it into an array. Would it help to have a separate array of these objects? If so, what operations would you do on the array, and what operations would you do on the old ArrayList?

To get the ArrayList as an array, you have to make an array and pass it into a method toArray (at least when dealing with specific objects). If the array is large enough, it's filled from the ArrayList. If it's too small, an array of the right size is returned. The best thing to do if you're not worried about efficiency, is to pass in a new zero-sized array and wait for the right sized array to be returned:

String[] arrayListArray = arrayList.toArray(new String[0]);

If that doesn't spark off anything, do a web search on "ArrayList" and the exception thrown, and see what others suggest.

If you need more help, here's the answers (or a couple of options, anyhow), and an additional task.