PowerPoint Presentation - The ArrayList Data Structure

advertisement
The ArrayList Data Structure
Standard Arrays at High Speed!
More Safety, More Efficient, and
Less Overhead!
The Java ArrayList Class
Java provides an ArrayList class to make it easier to
work with arrays.
An ArrayList is a one-dimensional array.
There is a lot of overhead code to set up a standard
array, fill it, track its logical size, and manipulate
values in the array. An ArrayList make these
operations easier.
However, an ArrayList holds only objects, not
primitive values like int, double, char or boolean.
But in particular Java has the Integer and Double
classes so you can place numbers in an ArrayList.
Instantiating an ArrayList
When you declare a standard array, you have to tell
Java a fixed number of memory locations that you
want the array to contain. During the run of a
program, this cannot be changed unless you create
a new standard array and copy all of the elements to
it. This would be awkward to do and implement in
every program that uses standard arrays.
When you declare an ArrayList, you don’t have to tell
Java how much storage space you need. The
ArrayList will be created for a beginning amount and
then it will automatically resize itself when it
becomes full and more elements need to be added.
Instantiating an ArrayList
Declaring and instantiating a standard array:
double [ ] nums = new double [20];
Declaring and instantiating an ArrayList:
ArrayList <Double> nums = new ArrayList <Double> ( );
No square bracket [ ] notation is used for an ArrayList.
Note the use of the templating angle brackets < and > that
enclose the type of object to be placed in the array.
Instantiating an ArrayList
Declaring and instantiating an ArrayList of other types:
ArrayList <Integer> nums = new ArrayList <Integer> ( );
ArrayList <String> names = new ArrayList <String> ( );
ArrayList <Student> students = new ArrayList <Student> ( );
ArrayList <Shape> shapes = new ArrayList <Shape> ( );
The ArrayList API says that all of the above ArrayLists will be
constructed with an initial capacity of ten.
Note the empty ( ) parentheses at the end of the constructor
call. Don’t forget to include these.
Instantiating an ArrayList
You can declare and instantiate an ArrayList with an initial
capacity of a certain size if you know approximately how
many elements you will place in the ArrayList.
The only real reason to do this is to keep the ArrayList from
automatically resizing itself over and over again until all
of the elements have been added to the ArrayList.
However, this is not particularly inefficient for today’s
computers unless you need to store many elements.
For example, if you know you will have 1000 random
integers in an ArrayList, you could use:
ArrayList <Integer> nums = new ArrayList <Integer> (1000);
Raw or Generic ArrayList?
When you instantiate an ArrayList as you have just seen, we call
it a generic ArrayList, because the programmer must specify
the element type for the list as in …
ArrayList <String> names = new ArrayList <String> ( );
Making a generic ArrayList with templating became available
beginning with Java 1.5 and higher.
Prior to that, programmers could only make a raw ArrayList,
where you could put all kinds of objects in the same ArrayList,
but care had to be taken to make sure only one kind of object
was placed in a list. You can still declare and instantiate a raw
ArrayList, like the following, but most compilers will “complain”
and at least give you a warning if you are using Java 1.5 or
higher. (some people refer to Java 1.5 as Java 5)
ArrayList names = new ArrayList ( );
Advantages of ArrayList
Operations are much much easier and less complex
for:
• traversing an ArrayList (accessing each element to
print or perform an operation on it)
• insertions anywhere in the ArrayList
• removals anywhere in the ArrayList
• searching an ArrayList
An ArrayList tracks its own logical size and grows or
shrinks automatically depending on the number of
elements it has.
ArrayList Differences
• Instead of using [] to manipulate elements, methods are
called to perform operations.
• An ArrayList tracks its logical size and physical size. We
don’t necessarily know what the physical size is and we
don’t need to, because if more memory locations are
needed then it will automatically resize itself. It is helpful
to be able to access the logical size of an ArrayList when
performing certain operations. The size() method is used
to get the number of elements in the list. The logical size
is 0 when an ArrayList is constructed and its logical size
is automatically adjusted when an element is added or
deleted.
• An ArrayList does have indices and the positions of the
elements range from index 0 to index logical size - 1.
java.util.ArrayList
The ArrayList class is part of the java.util package. So it is
necessary to import this class by including:
import java.util.ArrayList;
The ArrayList class implements the List interface.
That means that the ArrayList class must have all of the
methods that are defined in the List interface. You will learn
more about interfaces very soon, but we want to make you
familiar with this fact now. The formal way to state this fact for
the ArrayList class is:
class java.util.ArrayList<E> implements java.util.List<E>
The E in <E> simply stands for any kind of object or class name.
Declaring Variables of type List
Declaring and instantiating an ArrayList where the variable is
of type List interface is the preferred way to go for many
programmers. As you gain more experience programming
you will understand why. Don’t worry about that for now.
Here is the alternate way to declare and instantiate the
ArrayList named students using the List interface:
List <Student> students = new ArrayList < Student > ( );
Compare this to the previous way:
ArrayList <Student> students = new ArrayList < Student > ( );
The java.util.List<E> interface
An interface tells you the method signatures of the methods
that classes that implement the interface must have.
Here is what part of Java’s List interface looks like:
public interface List
{
public int size ( );
public boolean add (E obj);
public void add (int index, E obj);
public E get (int index);
public E set (int index, E obj);
public E remove (int index);
…….
}
ArrayList and LinkedList use the List Interface
A second class named the LinkedList class also implements the List interface.
Since both of these classes have the same methods (but different code for
them), we could choose to use the following declaration:
List < Student > students = new LinkedList < Student > ( );
instead of …
List <Student> students = new ArrayList < Student > ( );
This is one of the advantages of declaring variables of type List, because we
don’t need to change any of the code in the program … only where
students is declared and instantiated if we want to have a different kind of
list.
Some of the code in the LinkedList class is more efficient that the ArrayList
class, because the LinkedList class is not based on a standard array but a
different kind of list. You will learn about that if you take Advanced
Computer Programming.
Declaring Variables of type List
Also, if we declare the variable shapes to be of type List
<Shape>, then if the Shape is the parent of several
classes like Circle, Rectangle, and Triangle, then we can
hold all of those kinds of objects in the same list. This
can be a real advantage. Now you are starting to learn
about inheritance!
List <Shape> shapes = new ArrayList <Shape> ( );
The ArrayList Subset of Methods
There are many methods in the ArrayList class if you
look up its API on line.
However, we only want to work with a few methods of
the ArrayList class … those in particular that you are
expected to know for the AP Exam.
You might not receive full credit on a free response
coding question if you try to use methods other than
the ones specified by the College Board.
The specified methods and what they do are listed on
the next slide.
The ArrayList Subset of Methods
ArrayList method
What the Operation Does
int size ( )
returns the logical size of the list
boolean add (E obj)
appends the object obj to the end of the list and returns true if
successful (the fact that it returns true may be helpful sometimes)
void add (int index, E obj)
inserts the object obj at position index where index fulfills the
expression 0 ≤ index ≤ size. If index is out of bounds in the range
of index < 0 || index > size(), then Java throws an
IndexOutOfBoundsException. Once obj is inserted, then the
elements at position index and higher are moved to the right so that
1 is added to their indices and then the logical size is adjusted.
Note: if there are 3 elements in the list at indices 0, 1, and 2, then
obj can be added at index 3 without an out of bounds error
E get (int index)
returns the element at position index in the list
E set (int index, E obj)
replaces the element at position index with obj and returns the
element formerly at the specified position
E remove (int index)
removes the element from position index in the list and then moves
all elements at position index + 1 and higher to the left …
subtracting 1 from their indices and then adjusting the logical size.
The element formerly at the specified position is returned
Wrapper Classes
The Integer and Double classes are called wrapper
classes, because they are used to “wrap up” primitive int
and double values as objects so they can be put in an
ArrayList or other kind of data structure.
We used the Integer and Double classes earlier this year
when we used …
Integer.parseInt() and Double.parseDouble()
to get the values from JTextFields or InputDialog boxes.
Now let’s look a little closer at the Integer and Double
classes see how to wrap up an int or double as an object.
Wrapping & Unwrapping ints
You don’t need to know the parseInt() method for the AP Exam,
but you do need to know how to use the following methods of
the Integer class:
The constructor that has one parameter that is an int.
If you want to wrap up an int, like 345, as an Integer object, then
you would use the constructor to wrap it up:
Integer intObj = new Integer(345);
You have now wrapped up the int 345 and made it an Integer
object and the variable intObj refers to that object!
To unwrap the Integer object intObj and get the int value 345 out
of it and store it in the int variable x, then you have to call the
intValue() method …
int x = intObj.intValue();
Wrapping & Adding Integers
For the ArrayList …
ArrayList <Integer> nums = new ArrayList <Integer> ( );
if we want to place the values 5, 10, and 15 in nums, in that
order, we would wrap them up and add them as follows:
Integer intObj1 = new Integer(5);
nums.add(intObj1);
// adds to the end of the list
Integer intObj2 = new Integer(10);
nums.add(intObj2);
// adds to the end of the list
You can also combine the lines by using …
nums.add(new Integer(15));
// adds to the end of the list
Autoboxing Integers
Prior to Java 1.5, with a raw ArrayList, you had to wrap up int
values. However, with the advent of Java 1.5 autoboxing
became available. Here is the same code with autoboxing:
ArrayList <Integer> nums = new ArrayList <Integer> ( );
nums.add(5);
// autoboxing 5 and adding it
nums.add(10);
// autoboxing 10 and adding it
nums.add(15);
// autoboxing 15 and adding it
However, the College Board still wants you to know how to wrap
up int values.
Unboxing Integers
Prior to Java 1.5 with a raw ArrayList, you had to unwrap int
values before using them. However, with the advent of Java 1.5
unboxing became available. Here is the code with unboxing:
int x = nums.get(0);
// get Integer at index 0 & unwrap using unboxing
int y = nums.get(1);
// get Integer at index 1 & unwrap using unboxing
int z = nums.get(2);
// get Integer at index 2 & unwrap using unboxing
Here intValue() is called automatically by Java to unwrap
the Integer object returned by get(i) so it can be stored in x,
y, or z.
You don’t have to call intValue() to unwrap because of
unboxing!
However, the College Board still wants you to know how to
unwrap Integer objects.
Wrapping & Unwrapping doubles
You don’t need to know the parseDouble() method for the AP
Exam, but you do need to know how to use the following
methods of the Double class:
The constructor that has one parameter that is a double.
If you want to wrap up a double, like 12.3, as a Double object,
then you would use the constructor to wrap it up:
Double floatObj = new Double(12.3);
You have now wrapped up the double 12.3 and made it a
Double object and the variable floatObj refers to that object!
To unwrap the Double object floatObj and get the double value
12.3 out of it and store it in the double variable d, then you have
to call the doubleValue() method …
double d = floatObj.doubleValue();
Wrapping & Adding Doubles
For the ArrayList …
ArrayList <Double> floats = new ArrayList <Double> ( );
if we want to place the values 5.5, 6.6, and 7.7 in floats, in
that order, we would wrap them up and add them as follows:
Double floatObj1 = new Double (5.5);
floats.add(floatObj1);
// adds to the end of the list
Double floatObj2 = new Double (6.6);
floats.add(floatObj2 );
// adds to the end of the list
You can also combine the lines by using …
floats.add(new Double (7.7));
// adds to the end of the list
Autoboxing Doubles
Prior to Java 1.5, with a raw ArrayList, you had to wrap up
double values. However, with the advent of Java 1.5 autoboxing
became available. Here is the same code with autoboxing:
ArrayList <Double> floats = new ArrayList < Double > ( );
floats.add(5.5);
// autoboxing 5.5 and adding it
floats.add(6.6);
// autoboxing 6.6 and adding it
floats.add(7.7);
// autoboxing 7.7 and adding it
However, the College Board still wants you to know how to wrap
up double values.
Unboxing Doubles
Prior to Java 1.5 with a raw ArrayList, you had to unwrap double
values before using them. However, with the advent of Java 1.5
unboxing became available. Here is the code with unboxing:
double b = floats.get(0);
// get Double at index 0 & unwrap using unboxing
double c = floats.get(1);
// get Double at index 1 & unwrap using unboxing
double d = floats.get(2);
// get Double at index 2 & unwrap using unboxing
Here doubleValue() is called automatically by Java to
unwrap the Double object returned by get(i) so it can be
stored in b, c, or d.
You don’t have to call doubleValue() to unwrap because of
unboxing!
However, the College Board still wants you to know how to
unwrap Integer objects.
Adding Elements to an ArrayList - add(obj)
The following code stores the first 100 multiples of 3 in nums in
order:
ArrayList <Integer> nums = new ArrayList <Integer> ( );
int value = 3;
for (int i = 0; i < 100; i++)
{
nums.add(value); // adds at the end of the list
value += 3;
}
Note: if nums was a standard array, we would use …
nums [i] = value;
in place of nums.add(value);
Getting Elements from an ArrayList - get(i)
The following code prints the values stored in nums with 10
values per line with a field width of 5:
for (int i = 0; i < nums.size(); i++)
{
if ( (i + 1) % 10 == 0 )
System.out.printf( “%5d%n”, nums.get(i) );
else
System.out.printf( “%5d”, nums.get(i) );
}
Note: if nums was a standard array, we would use …
System.out.printf( “%5d”, nums[i] );
Getting Elements from an ArrayList - get(i)
To obtain the first element in an ArrayList always use …
nums.get(0);
To obtain the last element in an ArrayList always use …
nums.get(nums.size() - 1);
Note that since there are num.size() elements in the ArrayList,
then the index of the first element is 0 and the index of the last
element is nums.size() - 1.
Removing Elements from a Position - remove(i)
The following code removes and prints all of the multiples of 6
from nums in a field width of 5:
int i = 0;
while ( i < nums.size() ) {
if ( nums.get(i) % 6 == 0 ) {
int x = nums.remove(i) ;
System.out.printf( “%5d”, x );
// don’t increment i because elements are shifted down
} else // if not evenly divisible by 6 increment i
i++;
}
Removing Elements from a Position - remove(i)
The following code removes and prints all of the multiples of 6
from nums in a field width of 5 using a for loop:
for (int i = 0; i < nums.size() ; i++)
{
if ( nums.get(i) % 6 == 0 ) {
int x = nums.remove(i) ;
System.out.printf( “%5d”, x );
i--; // to cancel the effect of i++ in loop header
}
}
Removing Elements from a Position - remove(i)
To delete the first element in an ArrayList always use …
nums.remove(0);
To delete the last element in an ArrayList always use …
nums. remove(nums.size() - 1);
Again, since there are num.size() elements in the ArrayList, then
the index of the first element is 0 and the index of the last
element is nums.size() - 1.
Adding Elements at a Position - add(i, obj)
The following code adds the integer 3 at the first of the list
named nums using the add(i, obj) method, where the list initially
contains 6, 9, 12.
nums.add (0, 3); // add 3 at index 0.
The list now contains: 3 6 9 12
The following code adds the integer 15 at the end of the list no
matter how many elements there are using the add(i, obj)
method.
nums.add (nums.size() , 15); // add 15 after the last element
Since nums.size() is 4 before adding 15, then 15 is added at
index 4. Obviously 3, 6, 9, &12 are in indices 0, 1, 2, & 3.
The list now contains: 3 6 9 12 15
Replacing Elements at a Position - set(i, obj)
Assume nums contains: 3 6 9 12 15
The following code replaces the element at index 2 with the
value 10 using the set(i, obj) method. It returns the replaced
element and prints it out.
int x = nums.set (2, 10); // replace 9 at index 2 with 10.
System.out.println(“The replaced value was ” + x);
The list now contains: 3 6 10 12 15
Replacing the last value in the ArrayList …
int x = nums.set (nums.size() - 1, 20);
The list now contains: 3 6 10 12 20
Download