Topic 8: Arrays

Version 3.31

Handouts: Inits.java

Two class days

First Day

Arrays are "programming constructs that group data into lists."

(8.1) Array elements

Arrays store multiple values, each at a numbered index or subscript. The least index is always 0. Referencing an array element:

x[5]

Array references can be part of expressions. Index values can be computed from expressions.

(8.2) Declaring and using arrays

Java arrays are objects; variables which reference them must be declared. Example:

int [] x;

declares an array x which stores integer (int) elements. Each array stores only one type of element.

The size of an array is not part of its type, but is part of its value:

x = new int[10];

instantiates an array of 10 integer elements — which are zeroes!

Listing 8.1 BasicArray: declares, initializes, and prints the elements of an array.

The for loop is handy for iterating through the elements of an array, e.g.,

for (int i = 0; i < x.length; i++)
  System.out.println(x[i]);

which is equivalent to

for (int y : x)
  System.out.println(y);

provided y is not used elsewhere.

The [] operator, signifying an array index, has the highest priority of all Java operators.

Bounds checking

In Java, index bounds are checked on array references; if the index is not valid, the system throws an ArrayIndexOutOfBoundsException. (Compare C, C++.) The exception, if not otherwise handled, aborts the program; see Chapter 10 for further information about exceptions.

Each array knows its length, which is x.length. Note that this is written without parentheses, unlike the length method for Strings.

Listing 8.2 ReverseOrder: uses iteration with reverse indexing to print a list of numbers backward.

Listing 8.3 LetterCount: uses two arrays to count the upper and lowercase (ASCII) letters in a String. It depends on the fact that the initial element values are zeroes. The String, which is somewhat array-like, is indexed using the charAt method. Note the calculated array subscripts.

Alternate array syntax

int [] x; // preferred
int x[];  // also permitted but less perspicuous

The type of x is int [], so why break it into two parts? For compatibility with C and C++?

Initializer lists

Arrays can be initialized with lists of element values enclosed in {}'s. Example:

int [] x = new int[] {1, 7, -10, 4, 29};

Note that the size of the list determines the size of the array, so you don't need a number in the brackets, in fact, it's an error if you put one in:

int [] x = new int[5] {1, 7, -10, 4, 29}; // syntax error

In fact, the entire new int[] part is optional, so you can write it like this:

int [] x = {1, 7, -10, 4, 29}; // not recommended

However, it's required in other contexts (outside of a declaration), so you'd better get into the habit of using it. The designers of the Java language did us no favor when they allowed an exception here to the syntax for array instances!

See Inits.java.

Listing 8.4 Primes: uses an initialization list for an array.

Arrays as parameters

An array is an object, so when the entire array is passed as an argument to a method, only its reference (pointer) is copied, and the method can mutate the array.

foo(x);

A new array object is also welcome as a parameter:

foo(new int[] {7, 21, 23});

Individual array elements also can be passed as arguments:

bar(x[5]);

(8.3) Arrays of Objects

An array can be declared with either primitive or reference type elements. See the first two figures in this section. Explain.

Listings 8.5/6 GradeRange/Grade: uses an array of objects (Grades) to print a table of grades and cutoffs.

Listings 8.7/9 Movies/DVDCollection/DVD: uses a DVDCollection object which contains a list/array of DVDs. The addDVD method inserts a new DVD at the end of the list; when the array becomes full, it creates a new array of twice the size and copies the old one into it.

See Figure 8.3: the UML diagram shows dependency, aggregation, and cardinality.

(8.4) Command-line arguments

In which public static void main (String [] args) is finally explained!

The main method of a program has an array argument which captures the command line parameters when the program is run.

Listing 8.10 NameTag: expects two arguments; run as

java NameTag GREETING NAME

(Replace GREETING and NAME with actual values.)

These arguments are always Strings, so if you want to interpret them as numbers, you've got to convert them.

Another Example

Write a program which adds the numbers on its command line and prints the sum.

Remember, these parameters are always Strings. To interpret as numbers, they must be converted, for example, with

Solution: Adder.java

(8.5) Variable length parameter lists

This is a new feature in Java 1.5; it allows calling a method with variable numbers of parameters:

foo(12, 9, 8);
foo(new int [] {12, 9, 8}); // also works
foo(7, 2, -14, 21, 28, 39);

Declaring a variable length parameter list:

public void foo (int ... data) { ... }

Within the method, the parameter data is actually an array, but the caller does not have to explicitly create the array (the compiler handles this transparently).

The varying parameters must be of the same type; otherwise, they could not be put into an array.

If other named parameters are used, they must precede the varying parameters.

Actually this is syntactic sugar, for we could do the equivalent using explicit arrays:

public void foo (int [] data) { ... }

foo(new int [] {12, 9, 8});
foo(new int [] {7, 2, -14, 21, 28, 39});

Listing 8.11/12 VariableParameters/Family: uses a constructor with a variable length parameter list.

Discussion

Second Day

(8.6) Two-dimensional arrays

Two-dimensional arrays usually represent a table with rows and columns. They require two subscripts:

t[1][5]

The first subscript indicates the row, and the second, the column.

Listing 8.13 TwoDArray: shows the common use of nested for loops to process a two-dimensional array

Listing 8.14 SodaSurvey: uses nested initialization lists {{...}} to initialize the array elements, and computes two averages: one over the four flavors of soda (the rows), and one over the 10 tasters (the columns).

Multidimensional arrays

Arrays can have more than two dimensions. However, such structures are not always the best solution. Sometimes it makes better sense to have an array of objects, where the objects contain arrays, and so on.

(8.7) Polygons and polylines

Polygons and polylines both contain multiple points; polygons are closed; polylines, open.

Graphics class methods for drawing them include drawPolygon, fillPolygon, drawPolyline (a Polyline cannot be filled because it is not closed). These methods take 3 arguments: array of x coordinates, array of y coordinates, and how many (x, y) points from the arrays are to be used.

The java.awt.Polygon class encapsulates these arrays of x and y coordinates into an object; see Figure 8.6 for constructors and methods.

Example: Listings 8.15/16 Rocket/RocketPanel use two polygons and a polyline to draw a space ship.

Exercise: Revise the Rocket example, using Polygon objects.

(8.8) Mouse events

Kinds of mouse event (see Figure 8.7): all of these are represented by the MouseEvent class, but different methods are called:

A MouseListener must define all five of these methods!

In addition, there are mouse motion events (same figure). A mouse motion is still represented by a MouseEvent, but requires a different kind of listener: MouseMotionListener.

A MouseMotionListener has these methods:

Each of these 7 methods receives a MouseEvent as its sole argument. The event can call the MouseEvent method getPoint() to determine the location of the event; it returns a java.awt.Point, which has public access to x and y instance variables.

Examples:

(8.9) Key events

Key events occur when a keyboard key is pressed, released, or typed. It's not clear (from the textbook) how "typed" is different from the other two. See Fig. 8.8, which describes the three methods to handle KeyEvents:

Each one receives a KeyEvent as argument. The interface is KeyListener.

The Java API documentation for the KeyEvent class provides clearer explanations of the differences between a key being pressed, released, and typed.

The KeyEvent class also defines constants, such as KeyEvent.KEY_UP, that represent each possible keystroke. (Where can we find the list of these? Again, in the Java API documentation for the KeyEvent class.)

Example: Listing 8.21/22 Direction/DirectionPanel draws an arrow which moves in response to the four arrow keys. It actually loads four images, with different orientations, and displays the appropriate one for the direction of motion.

Image s are created with ImageIcon(filename) and drawn with the Graphics method paintIcon(observer, graphics, x, y), where (x, y) are the location for drawing the image, and observer is an "image observer," something that can manage loading of images. (A JPanel is suitable as an image observer.)

Autorepeating of keys: holding a key down may cause it to emit its character repeatedly and rapidly. This is controlled by the window manager or the X Window system. This would generate only one key press event and one key release, but multiple key typed events.

Keyboard focus: the graphics component with keyboard focus (also called just focus) is the one that receives keyboard input. The (Component?) method setFocusable (true/false) makes a component focused (focusable?) or not. Usually, a mouse click on a component makes it focused; but depending on how your window manager is configured, just hovering over a window also might make it focused.

Discussion


  1. Version log:
    • Version 3.3, 2012 Mar 3. Updated for 7th edition.
    • Version 3.2, 2012 Feb 7. Moved ArrayLists to lec-ch05.txt.
    • Version 3.1, 2011 Mar 12. Converted to markdown.
    • Version 3.0.1, 2010 Mar 15. Typographical corrections.
    • Version 3, 2010 Mar 9. Converted to RST.
    • Version 2, 2009 Mar 18. Revised for 6th edition.