Arrays and Collections
The Collections Framework
A collection — sometimes called a container — is simply an
object that groups multiple elements into a single unit. Collections are
used to store, retrieve, manipulate, and communicate aggregate data.
Typically, they represent data items that form a natural group, such as a
poker hand (a collection of cards), a mail folder (a collection of
letters), or a telephone directory (a mapping of names to phone
numbers).
http://java.sun.com/docs/books/tutorial/collections/index.html
Java provides a Collections Framework, a set of classes in the java.util
package, that enable the programmer to store and manipulate data in various
ways. This library makes it very easy for the programmer to create and
manipulate collections of information. Additionally, the implementations are
optimized for efficiency. Many other programming languages also support a
similar library.
Though having such a library makes life easier for the programmer, it is
extremely important that students learn how such libraries are implemented.
CS 112 and CS 245 both focus heavily on the implementation and performance
issues associated with building various types of collections.
Arrays
The array is the most basic type of collection. Though other
types of collections are easier to use, we'll begin with arrays. It is very
important for you to understand how to use and manipulate arrays.
An array allows the programmer to store a list of elements, all of the
same type, in a contiguous block of memory. The size of an array must be
specified when it is instantiated and cannot change.
+Declaring Arrays
An array declaration creates a reference to the first element of the
array. The declaration includes the type of the elements that will be stored
in the array, a name for the array, and the square brackets ([]) specify that
the variable will be an array.
The previous example declares a reference to the array, but does not
instantiate the array. Note that the example does not specify the size of the
array. To instantiate the array, the
new operator must be used.
//declare a reference to the array
int[] numbers;
//instantiate an array of 10 integers
numbers = new int[10];
//alternative: declare and instantiate all at once
double[] scores = new double[10];
It is also possible to assign values to each position of an array at the time
of instantiation. The initializer list is used for this purpose:
//declare an array of size 5 called numbers and
//initialize its elements to 1, 2, 3, 4, and 5
//respectively
int[] numbers = {1, 2, 3, 4, 5};
+Accessing Individual Array
Elements
Each array element has a subscript that identifies its position
in the array. It is extremely important to remember that the subscripts begin
at 0. Therefore, an array of size 5 would have subscripts 0, 1, 2, 3, and 4.
To access an array element, specify the name of the array followed by the
element's subscript in square brackets. The subscript may also be represented
by an int variable or expression that results in an int value.
int firstElement = numbers[0];
System.out.println("The second score is " + scores[1]);
int toChange = 3;
numbers[toChange+1] = 75; //use the assignment operator to change a value
If your program attempts to access an array element that does not exist, you
will experience a runtime ArrayIndexOutOfBoundsException. Make sure that the
number you place between the square brackets is a valid index for the given
array.
+Arrays and Loops
Arrays and for loops go hand in hand. It is quite common to use a for loop
to iterate through every element of an array and perform a specific action.
The example below initializes every element of the array numbers to
100.
int[] numbers = new int[10];
for (int i = 0; i < numbers.length; i++) {
numbers[i] = 100;
}
Notice that the length of an array can be retrieved by using the dot
operator to access the member length. However, it is important to
note that the length of an array is the total number of elements one can
store in the array. It is certainly possible that the number of valid
elements in an array is smaller than the total number of elements the array
can store. In this case, it is common to keep a separate integer variable to
represent the number of valid elements in an array.
+Arrays and Methods
A single array element can be passed to a method, as can an entire array.
If an entire array is passed into a method, a reference to the
original array is passed. As a result, any changes made to the array by the
method will be reflected in the caller.
public class ArraySamples {
public static void printOne(int oneNumber) {
System.out.println(oneNumber);
}
public static void printAll(int[] manyNumbers) {
for(int i = 0; i < manyNumbers.length; i++) {
System.out.println(manyNumbers[i]);
}
manyNumbers[0] = 1000; //perhaps a mistake?
}
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
printOne(numbers[3]);
printAll(numbers);
System.out.println(numbers[0]); //prints 1000
}
}
+Arrays of Objects
Each element of an array may be an object, not simply a primitive type. In
this case, the array variable is a reference to a list of references. Each
element of the array is a reference to an object. When the array itself is
created, the objects are not instantiated (as shown below).
//assume a class Name exists
Name[] names = new Name[5];
Below, we create two new objects of type Name and place their addresses in
positions 0 and 1 of the array, respectively.
names[0] = new Name("Bob", "Smith");
names[1] = new Name("Jane", "Wu");
+Inserting Elements into a Sorted
Array
Often, it is necessary to maintain a sorted array of elements. In this
case, adding a new element to the array can be quite a challenge. If the
element's value dictates that it should be inserted anywhere but in the
rightmost position, the insert procedure must shift the the right all
elements that come after the element to be inserted. The following example
implements a procedure to insert an element in the first position of the
array.
/**
* Takes as input a newValue and inserts it at position 0 of the array values.
* If the array is full, the method does nothing.
* @param newValue - the new value to insert at position 0
*/
public void insertAtZero(int newValue) {
//this method would be implemented in a class with a data member
//values and a data member count
if(count >= values.length) {
return;
}
for(int i = count; i > 0; i--) {
values[i] = values[i-1];
}
values[0] = newValue;
count++;
}
Notice that the method returns in the case that the array is full.
Clearly, this solution is less than optimal. It is quite common to implement
such an insertion procedure such that if the array is full, the method will
allocate a new array larger than the current array and copy all of the
elements from the current array into the new array. Keep in mind that the
reference to the old array must then be changed to refer to the new array.
Exercises:
- Write a piece of code to test this method.
- Modify the method so that it inserts the newValue at the correct
position such that the array is maintained in sorted order.
- Modify the method so that it resizes the array when it becomes
full.
+Deleting Elements from a Sorted
Array
Similar to insertion, deletion of elements from a sorted array requires
that all elements to the right of the element removed be moved to the left
one position. The following example illustrates a procedure to delete the
element at position 0 of an array.
/**
* Takes as input an array and the number of elements in the array and
* removes the element at position 0. If there are no elements in the
* array, the method does nothing.
* @param values - the array of values
* @param count - the number of values stored in the array
*/
public void removeFromZero(int[] values, int count) {
if (count <= 0) {
return;
}
for(int i = 0; i < (count-1); i++) {
values[i] = values[i+1];
}
}
Exercises:
- Write a piece of code to test this method.
- Modify the method so that it will take as input the value of the item
to be remove and remove that value.
+Two-Dimensional Arrays
Java also supports two-dimensional arrays. All of the data in a
two-dimensional array must be of the same type. However, you can imagine the
data stored in a matrix of several rows and columns. To declare a
two-dimensional array, you simply use two sets of square brackets. Similarly,
the access and modify elements of a two-dimensional array, you must specify
the element's row and column.
//declare a 2D array with 5 rows and 10 columns
//the array might represent 10 homework scores for each
//of 5 students
double[][] scores = new double[5][10];
scores[0][0] = 90;
Array Lists
The java.util package provides a class ArrayList
that efficiently provides the functionality of a standard array.
Additionally, the ArrayList allows the programmer to insert new items anywhere
in the list, without having to move other elements, and it also automatically
resizes the underlying array when it becomes full. Feel free to browse the
API to get a sense for the types of methods supported by the ArrayList.
Unfortunately, for now you will be required to stick to arrays. We'll revisit
use of ArrayLists as the semester progresses.
Sami Rollins
Date: 2007-08-10