| CSCI A201/A597Lecture Notes 23 Spring 2000 |
Arrays represent a ubiquitous data structure meant to simplify the processing of data by indexing it. If you understand the concept of variable you will have no problem understanding the concept of array.
Arrays (like variables in general) are simply ways of using the computer memory in your programs. In case of arrays you can allocate space for more than one location at a time, and refer to any of the allocated locations by the same name, and using an index.
Here are some examples to illustrate this point:
public class Apr04 {
public static void main(String[] args) {
int n = 12; // [1]
int[] m; // [2]
m = new int[n]; // [3]
for (int i = 0; i < m.length; i+=1) { // [4]
System.out.println(i + ": " + m[i]); // [5]
} // [6]
}
}
Here's a description of this program step by step:
import java.util.Random;
public class Apr04 {
public static void main(String[] args) {
Random rand = new Random();
int n = 12;
int[] m;
m = new int[n];
for (int i = 0; i < m.length; i+=1) {
m[i] = Math.abs(rand.nextInt()) % (50 - 30 + 1) + 30;
}
int sum = 0;
for (int i = 0; i < m.length; i+=1) {
System.out.println(i + ". Adding: " + m[i]);
sum += m[i];
}
System.out.println("The total is: " + sum);
}
}
What does it do? Here's another one.
This time the array is of String's.
public class Apr04 {
public static void main(String[] args) {
String[] months;
months = new String[12];
months[0] = "Jan";
months[1] = "Feb";
months[2] = "Mar";
months[3] = "Apr";
months[4] = "May";
months[5] = "Jun";
months[6] = "Jul";
months[7] = "Aug";
months[8] = "Sep";
months[9] = "Oct";
months[10] = "Nov";
months[11] = "Dec";
for (int i = 0; i < months.length; i+=2) {
System.out.println(months[i]);
}
}
}
Where can you get an array of String's already initialized? Exactly: from the command line.
Here's an example:
frilled.cs.indiana.edu%cat Apr04.java
public class Apr04 {
public static void main(String[] months) {
for (int i = 0; i < months.length; i++) {
System.out.println(months[i]);
}
}
}
frilled.cs.indiana.edu%javac Apr04.java
frilled.cs.indiana.edu%java Apr04 Jan Feb Mar Apr May Jun Jul Aug Sep
Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
frilled.cs.indiana.edu%
This particular array is built automatically by the Java run-time system
for you, based on what you type on the command-line.
The array is made out of String's so if you want to look at
them as numbers you need to parse the String's first.
Here's computing the sum of a sequence of numbers specified on the command line:
frilled.cs.indiana.edu%cat Apr04.java
public class Apr04 {
public static void main(String[] months) {
int sum = 0;
for (int i = 0; i < months.length; i++) {
int n = Integer.parseInt(months[i]);
sum += n;
}
System.out.println(sum);
}
}
frilled.cs.indiana.edu%javac Apr04.java
frilled.cs.indiana.edu%java Apr04
0
frilled.cs.indiana.edu%java Apr04 1 2 3
6
frilled.cs.indiana.edu%java Apr04 6 9
15
frilled.cs.indiana.edu%
Multidimensional arrays use more than one index to locate a location. We've seen (at least conceptually) two-dimensional arrays.
Here's one, in which the elements are all char.
frilled.cs.indiana.edu%cat Apr04.java
public class Apr04 {
public static void main(String[] args) {
int size = Integer.parseInt(args[0]);
char[][] letter;
letter = new char[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (i == 0 || i == size-1 || i+j == size-1) {
letter[i][j] = '*';
} else {
letter[i][j] = ' ';
}
}
}
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
System.out.print(" " + letter[i][j]);
}
System.out.println();
}
}
}
frilled.cs.indiana.edu%javac Apr04.java
frilled.cs.indiana.edu%java Apr04
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at Apr04.main(Compiled Code)
frilled.cs.indiana.edu%java Apr04 10
* * * * * * * * * *
*
*
*
*
*
*
*
*
* * * * * * * * * *
frilled.cs.indiana.edu%
What's the difference to the method used at the first practical?
We've seen one arrays and variables being used in main.
What if we pass them as arguments to a procedure.
Will it make a difference?
Let's experiment.
Stage one: pass a variable to a method.
frilled.cs.indiana.edu%
cat Apr04.java
public class Apr04 {
public static void main(String[] args) {
int n;
n = 10;
System.out.println("main before addOne n is " + n);
Library.addOne(n);
System.out.println("main after addOne n is " + n);
}
}
class Library {
public static void addOne(int n) {
System.out.println("... addOne receives n as " + n);
n = n + 1;
System.out.println("... addOne changed n to " + n);
}
}
frilled.cs.indiana.edu%javac Apr04.java
frilled.cs.indiana.edu%java Apr04
main before addOne n is 10
... addOne receives n as 10
... addOne changed n to 11
main after addOne n is 10
frilled.cs.indiana.edu%
Can you explain what happens, step by step? Let's do the same by passing an array.
frilled.cs.indiana.edu%cat Apr04.java
public class Apr04 {
public static void main(String[] args) {
System.out.println("Initializing array.");
int[] n = { 1, 2, 3, 4, 5, 6 };
System.out.println("Printing array: ");
for (int i = 0; i < n.length; i++) {
System.out.print(n[i] + " ");
}
System.out.println();
System.out.println("Calling addOne on the array.");
Library.addOne(n);
System.out.println("Back in main the array looks like this:");
for (int i = 0; i < n.length; i++) {
System.out.print(n[i] + " ");
}
System.out.println();
System.out.println("End of program.");
}
}
class Library {
public static void addOne(int[] n) {
System.out.println("... in addOne the array received is: ");
for (int i = 0; i < n.length; i++) {
System.out.print(n[i] + " ");
}
System.out.println();
System.out.println("... now we change it to: ");
for (int i = 0; i < n.length; i++) {
n[i] += 1;
}
System.out.println();
for (int i = 0; i < n.length; i++) {
System.out.print(n[i] + " ");
}
System.out.println();
System.out.println("... and return to main.");
}
}
frilled.cs.indiana.edu%javac Apr04.java
frilled.cs.indiana.edu%java Apr04
Initializing array.
Printing array:
1 2 3 4 5 6
Calling addOne on the array.
... in addOne the array received is:
1 2 3 4 5 6
... now we change it to:
2 3 4 5 6 7
... and return to main.
Back in main the array looks like this:
2 3 4 5 6 7
End of program.
frilled.cs.indiana.edu%
See the difference? Let's finish with three small examples.
What's this one doing?
public class Apr04 {
public static void main(String[] args) {
int size;
int[] n;
size = args.length;
n = new int[size];
for (int i = 0; i < n.length; i++) {
n[i] = Integer.parseInt(args[i]);
}
}
}
It is allocating an array and filling it with
the values received on the command line. The array
inside is of the same size as the one created and
passed to main by the Java run time
system. Of course, this is redundant, but a good exercise.
Computing the max.
frilled.cs.indiana.edu%cat Apr04.java
public class Apr04 {
public static void main(String[] args) {
int max = Integer.parseInt(args[0]);
for (int i = 0; i < args.length; i++) {
if (max < Integer.parseInt(args[i])) {
max = Integer.parseInt(args[i]);
}
}
System.out.println("Max is: " + max);
}
}
frilled.cs.indiana.edu%javac Apr04.java
frilled.cs.indiana.edu%java Apr04 -3 1 -9 2 5 -6
Max is: 5
frilled.cs.indiana.edu%
You've seen this before, hopefully it's clearer now. It's a combination of new algorithm and new syntax, hopefully refreshing.
Let's look at arrays of Circles.
import java.util.Random;
import element.*;
public class Apr04 {
public static void main(String[] args) {
DrawingWindow d = new DrawingWindow();
Random gen = new Random();
int size = Integer.parseInt(args[0]);
Circle[] circles = new Circle[size];
for (int i = 0; i < size; i++) {
circles[i] = new Circle(Lib.m1(gen, 30, 170),
Lib.m1(gen, 30, 170),
Lib.m1(gen, 20, 40));
}
for (int i = 0; i < circles.length; i++) {
d.draw(circles[i]);
}
}
}
class Lib {
public static int m1(Random r, int left, int right) {
return Math.abs(r.nextInt()) % (right - left + 1) + left;
}
}
(Red squares with two-dimensional arrays: it could
simplify the overall procedure).
Next step would be to move the circles with the mouse. For this
we would have to fill them and also (since it's easier) use the
invertMode drawing mode.