Arrays & Arraylists: 9.1 Array Basics
Arrays & Arraylists: 9.1 Array Basics
This works well if we're only corraling four sheep but would become unwieldy if we had 10
sheep, and beyond ridiculous if we have 50 sheep. There has to be a better way to manage
large amounts of data, and in fact there are several.
In this chapter we'll look at arrays, a traditional programming tool to collect a large amount of
data into one object that we can process. We'll use them to efficiently create games with more
elements. We'll also look at ArrayLists, a Java object that provides a more powerful tool to
handle a lot of data.
For the Free Java Book, you can cover either arrays alone or arrays and ArrayLists to continue
your work. You don't have to study both, though both are more fully covered in later chapters.
Here's a conceptual visualization of an array, let's call it words, that holds the words in the
sentence 'Java is a powerful language'.
and here's an example array of UFOs, assuming UFO is an already created object.
The size of an array is almost always declared with a constant as shown above. The constant is
very convenient for further array processing.
String[ ] words;
words = new String[MAX_WORD];
The values in an array are automatically initialized. Numeric values are initialized to 0, char
values are initialized to the char that has ASCII value 0, booleans to false and objects to null.
words[0] = "Java";
words[1] = "is";
words[2] = "a";
words[3] = "powerful";
words[4] = "language";
If we wanted to assign a value read from the keyboard value we might have
Assigning a value to an array position replaces the existing element at that position.
There is no built in method for inserting an element into an array and moving the array
elements to make room, or for deleting an element and moving the elements to take up the
deleted element's position.
or
words may also be traversed forwards (only) using an enhanced for loop as shown here.
for(String w : words)
{ println(w); }
Note that localName is declared inside the for loop and so has scope limited to the for loop.
Traversing an array in the head to tail direction is a forward traversal, and the reverse is a
backward traversal.
println(words.length);
ArrayBasics
//ArrayBasics.java
import acm.program.*;
println("\n");
print("The length of words is: " + words.length);
println("\n");
words[0] = "Java";
words[1] = "is";
words[2] = "a"; load the array
words[3] = "powerful"; and display it
words[4] = "language";
display(words);
println("\n");
create a reverse
String [ ] revWords = reverse(words);
copy of the array
display(revWords);
println("\n");
println("Now crashing the program...");
words[MAX] = "Going for a walk off the end of the array!";
} //run
This message appears in the command window when the program crashes
Exception in thread "main" java.lang.ArrayIndexOutOfBound
at ArrayBasics.run(ArrayBasics.java:35)
…several more lines of error information…
cb1Box = cb1.getBounds( );
individually get the bounding
cb2Box = cb2.getBounds( );
cb3Box = cb3.getBounds( ); rectangles around the cannonballs
blockerBox = blocker.getBounds( );
While using the exact same Cannonball and Blocker classes as before, let's write a version that
works with any reasonable number of cannonballs. Some examples of the needed modications
are discussed here.
Instead of declaring each of the cannonballs individually we declare an array of cannonballs and
then initialize each individually.
Cannonball[ ] cbs;
cbs = new Cannonball[CB_COUNT];
cbs[0] = new Cannonball();
cbs[1] = new Cannonball(Color.GREEN);
cbs[2] = new Cannonball(Color.YELLOW);
cbs[3] = new Cannonball(Color.RED);
We use a RandomGenerator rg to place all of the cannonballs in the window, which has width
AW.
for(Cannonball c : cbs)
{ add(c, rg.nextInt(0, AW-50), 0); }
There are unique x and y movements for each cannonball, so we record the x movements in
one array and the y movements in another.
As the game progresses we attempt to block the droppping cannonballs. For every cannonball
still in the game, we check it for being blocked and bounce the cannonball if it is.
Our game will end when 10 seconds of play have elapsed or all of the cannonballs have escaped
the window. The addDone boolean method below checks the 'out of game' status of each
cannonball. If a cannonball isn't finished then the loop is exited and the method returns false,
indicating that not all of the cannonballs are out of the game. If the array traversal loop
finishes, then all of the cannonballs are out of the game and so true is returned.
returns false if a cannonball is
public boolean allDone(boolean[ ] cbd) identified that isn't out of the
{ window, indicating that not all
for(boolean done : cbd)
cannonballs are finished
{ if (done == false) return false; }
return true;
} //alldone returns true if all the cannonballs
are out of the game
9.2.2 CannonadeWithArrays
Below is the full program that implements a version of Cannonade2 with four cannonballs, but
it could be extended to many more with very little effort.
CannonadeWithArrays
//CannonadeWithArrays.java
import acm.program.*;
import acm.graphics.*;
import acm.util.*;
import java.awt.*;
©Daniel L. Schuster, 2009, all rights reserved Page #9
import java.awt.event.*;
Cannonball[ ] cbs;
Blocker blocker;
int time, score;
GLabel scoreLbl;
time = 0;
score = 0;
scoreLbl = new GLabel(""+score);
scoreLbl.setFont("SanSerif-BOLD-30");
scoreLbl.setColor(Color.RED);
add(scoreLbl, 2, 26);
addMouseListeners( );
waitForClick( );
} //init
©Daniel L. Schuster, 2009, all rights reserved Page #10
public void mouseMoved(MouseEvent e)
{
double x = e.getX( );
double y = e.getY( );
blocker.setLocation(x-40, y); //center blocker under mouse
} //mouseMoved
bounding rectangles
public void run( ) of the cannonballs
{
RandomGenerator rg = new RandomGenerator( );
GRectangle[ ] cbBoxes = new GRectangle[CB_COUNT];
GRectangle blockerBox;
Here's a visual representation of an ArrayList, let's call it words, that holds the words in the
sentence 'Java is a powerful language'.
words
0 1 2 3 4
Java is a powerful language
import java.util.ArrayList;
or
import java.util.*;
An ArrayList suitable for storing for the sentence above(‘Java is a powerful language’), word
by word, can be created with the statement
Note the optionalBeginningSize. You may specify the initial size (number of 'spaces' available),
but the ArrayList will grow as needed to accommodate more objects added to it. Or you can
leave the optionalBeginningSize out, in which case the ArrayList will be initially set to the
default value 10. The ArrayList will still grow if needed.
Alternatively you can also declare an ArrayList in one statement and instantiate it in another.
Like the objects we've worked with before, ArrayLists have many useful methods for
manipulation and we'll look at those now.
words.add("Java");
words.add("is");
words.add("a");
words.add("powerful");
words.add("language");
The add( ) method puts elements at the end of the ArrayList. If the ArrayList is not large
enough then it is automatically enlarged to accommodate additional information.
If we wanted to add a value read from the keyboard value we might have
An element can also be inserted into an ArrayList using the Java method add(index, value)
method. The existing elements 'slide' toward the tail of the list, making room for the new
element. Thus
words.add(0, "Sun's");
0 1 2 3 4 5
Sun's Java is a powerful language
and then
words.add(4, "very");
words.add(6, "programming");
gives us
0 1 2 3 4 5 6 7
Sun's Java is a very powerful programming language
words.add(8, "!");
which would add a '!' to the end of words, but you cannot adding any farther past the tail of the
ArrayList.
words may also be traversed forwards only using an enhanced for loop as shown here.
for(String w : words)
{ println(w); }
Note that localName is declared inside the for loop and so has scope limited to the for loop and
can't be used outside the loop.
Traversing an ArrayList in the head to tail direction is a forward traversal, and the reverse is a
backward traversal.
9.3.4 Size Related Methods
println(words.size( ));
An ArrayList may be checked for being empty (having no elements) with the isEmpty( )
boolean method.
if (words.isEmpty( ) == false)
{ …doSomething… }
The expression arraylist.size( ) – 1 calculates the index of the last filled space in the ArrayList
and can be used to traverse words no matter what the size it is. The code segment below
traverses it in reverse order.
words.remove(0);
we have
0 1 2 3
is a powerful language
If we then execute
words.remove(1);
words.remove(1);
we have
0 1
is language
©Daniel L. Schuster, 2009, all rights reserved Page #17
because the first remove( ) deleted the "a" in position 1 and collapsed words, and the second
remove( ) deleted the "powerful" now in position 1 and again collapsed words.
The collapsing of the ArrayList has significant implications for using the remove( ) method
inside a loop. Let's begin by assuming that words is
0 1 2 3 4 5
Java is a practical programming language
and note that the Strings containing "p" are in positions 3 and 4.
Now, in a loop starting a 0, remove every String that contains a 'p' using this code segment.
0 1 2 3 4
Java is a programming language
due to collapse of the ArrayList. Also note that the index variable i was 3 when we removed
the word "practical" but becomes 4 due to the i++. 'programming' is now in position 3 and has
been skipped. So the next remove( ) looks at "language", which does not have a "p". We have
0 1 2 3 4
Java is a programming language
Because of this using remove( ) inside a loop is very problematic if there is any possibility of
more than one item being removed. It is usually best to avoid it.
display(words);
display(reverseWords(words));
words.add("Java");
words.add("is");
println("Current size: " + words.size( ));
words.add("a");
words.add("powerful");
words.add(readLine("Last word? "));
println("\nTraverse by index");
for(int i=0; i<5; i++)
{ print(words.get(i) + " "); }
print( "\n\n");
println("Reverse traverse by index");
for(int i=words.size( )-1; i>=0; i--)
{ print(words.get(i) + " "); }
print("\n\n");
println("Add values");
words.add(0, "Sun's");
words.add(4, "very");
words.add(6, "programming");
for(int i=0; i<=words.size( )-1; i++)
{ print(words.get(i) + " "); }
print("\n\n");
println("Remove and size 1");
println("Size: " + words.size( ));
words.remove(0);
for(int i=0; i<=words.size( )-1; i++)
{ print(words.get(i) + " "); }
print("\n\n");
println("Remove and size 2");
println("Size: " + words.size( ));
words.remove(3);
print("\n\n");
println("Set");
words.set(0, "Suns's Java");
words.set(4, "programming language");
words.add(5, "but I prefer Captain Crunch");
for(int i=0; i<=words.size( )-1; i++)
{ print(words.get(i) + " "); }
} //run
} //ArrayListBasics
Current size: 2
Last word? language
Traverse by index
Java is a powerful language
Add values
Sun's Java is a very powerful programming language
Set
Suns's Java is a powerful programming language but I prefer Captain Crunch
Traversing an ArrayList using an int index works perfectly well, but we can also do it with a list
iterator. We'll restrict our application of list iterators to traversals but be aware that there is
much more to list iterators than we discuss here.
litr is a ListIterator for String objects and is positioned before the first String in words. In
general a list iterator is declared with
while(litr.hasNext( ))
{
String w = litr.next( );
print(w + " ");
}
litr has now been moved so that it is positioned after the last String in words, so traversing
from tail to head is now possible.
while(litr.hasPrevious( ))
{
String w = litr.previous( );
print(w + " ");
}
ArrayList<Cannonball> cbs;
cbs = new ArrayList<Cannonball>(CB_COUNT);
cbs.add(new Cannonball( ));
cbs.add(new Cannonball(Color.GREEN));
cbs.add(new Cannonball(Color.YELLOW));
cbs.add(new Cannonball(Color.RED));
We use a RandomGenerator rg to place all of the cannonballs from the ArrayList cbs in the
window, which has width AW. Note that this is exactly the same enhanced for loop as we used
for arrays.
for(Cannonball c : cbs)
{ add(c, rg.nextInt(0, AW-50), 0); }
For every cannonball still in the game, check it for being blocked and bounce the cannonball if it
is. The code is almost exactly the same as that for arrays.
ArrayList<Cannonball> cbs;
Blocker blocker;
int time, score;
GLabel scoreLbl;
time = 0;
score = 0;
scoreLbl = new GLabel(""+score);
scoreLbl.setFont("SanSerif-BOLD-30");
scoreLbl.setColor(Color.RED);
add(scoreLbl, 2, 26);
for(Cannonball c : cbs)
{ add(c, rg.nextInt(0, AW-50), 0); }
addMouseListeners( );
waitForClick( );
} //init
scoreLbl.setLabel("" + score);
if (allDone(cbsOutOfGame) == true)
{ break; }
} //game loop
ShowEvenValues Write a program that loads an array with 20 random integers using a loop.
Now display only values that are even numbers.
TooBig1 Write a program that loads an array with 10 random doubles using a loop. Now
attempt to print 11 values from the array. What happens and why?
LoadSquares Load an array with the integers 25, 36, 49, …, 144. Traverse the array, calculating
the sum which is then displayed.
ArrayOfStrings Write a program that loads 5 Strings from the keyboard using a loop, then
displays them in reverse order.
BackAndForth Write a program that loads and array with 10 random integers using a loop. Now
print those elements in order, then in reverse order, then prints 5 of them randomly.
ArrayEqual Write a program that loads two arrays of chars from the keyboard. Now write a
boolean method isEqual(char[] a1, char[] a2) that tests the arrays for equality.
InsertAndDelete Write a program that declares an array of 10 strings. Now load the array of
with 6 strings from the keyboard, putting them in positions 0 through 5 in the array, leaving
positions 6 though 9 empty. Now present the user with a menu.
a) delete string – the user inputs an integer representing a position to delete. If the
position is currently occupied then move all of the strings after this position one "forward",
overwriting the values already there. Empty spots are filled with "", an empty string. If the
position is not currently occupied the deletion is denied.
b) insert string – the user specifies a position and a string. If the position is already
occupied, then the strings are all moved one position "backward", making room for the new
string, which is inserted. The last item "drops off" the array if necessary. If the position is
not already occupied the insertion is denied.
c) display array – neatly display the entire array.
Graphics Program
PlaceUFOs Recall the UFO2 class that allowed us to create a default UFO and a custom colored
UFO. Write a program that loads an array of 10 UFO2s and adds them randomly in the window.
UFORace Write a program that places 4 UFOs at random heights along the left edge of the
window. The UFOs move, with differing velocity, to the right edge. When the edge is reached
the losing ufos are removed and the winner flashes on and off.
UFOShootDown Create a ufo shooting game that allows you to shoot at a target as it moves
across the screen. There is only one target on screen at a given time, the speed, size and
starting location of the targets vary. As you shoot at a target you can see the bullets fly upward
and you can fire multiple shots at a target. The gun is at the bottom of the window and moves
left and right with the mouse and fires with a mouse click.
Points earned 38
bullets in
flight
12
DrawingProgram Create a mouse controlled drawing program that allows you to draw
rectangles, ovals and lines. You'll need arrays (or arraylists) to store the components of your
graphic images as they are created. The program, with a ufo that's been drawn might look like
this:
Rectangle
Oval
Line
Copy Delete Paste
Colors