C SC 205 Lecture 8: ArrayList class specification
major resources: Data Structures and the Java Collections Framework Second Edition,
William Collins, McGraw-Hill, 2005
Introduction to Programming and OO Design
using Java, Niño and Hosch, Wiley & Sons, 2002
[ previous
| schedule
| next ]
Wednesday October 3 (week 4)
ArrayList specification
- tour of Java API documentation
- see http://math.otterbein.edu/home/java/j2sdk1.5/docs/api/java/util/ArrayList.html
- One constructor and the addAll() method accept a collection as parameter
- declaration for that parameter is: Collection <? extends E> c
- note that E is the ArrayList class parameter, e.g. public class ArrayList<E>
- by using Collection interface as parameter type, the argument class can be
any that implements the Collection interface, provided that...
- by parameterizing it with <? extends E>, the parameter of the argument class can be
E or any class that extends/implements E
- Example:
interface Shape { }
class Ellipse implements Shape { }
LinkedList<Ellipse> first = new LinkedList<Ellipse>();
// add some elements to first
ArrayList<Shape> second = new ArrayList<Shape>( first );
The argument in the last statement is of type LinkedList<Ellipse>, which
is type-compatible with the parameter (Collection<Shape>) because LinkedList implements Collection
and Ellipse implements Shape
- The above essentially says that we can initialize any new collection with any existing
collection (even if their implementations differ vastly), so long as the elements of the existing
collection are of a compatible type. How powerful!
Interesting Interfaces implemented by ArrayList
- Three of the interfaces implemented by ArrayList are marker interfaces: an interface with no methods, implementing one simply marks
your class such that operations like instanceof will indicate the relationship
- RandomAccess - implement this if your list is based on a data structure having
random access (constant time) to list elements (e.g. array). Some utilities such as Collections
searching and sorting methods can use this to choose the most efficient algorithm to use.
- Serializable - this indicates an object of this class can be "flattened out" for insertion into
a byte stream to write it to a file, network, etc. And that it can be reconstructed when read from a byte stream.
- Cloneable - more details below.
Related Java concept: Cloneable and cloning
- to clone an object is to make a copy of it
- but cloning makes a copy in a very specific way: not all copies are clones!
- every class inherits the clone() method from class Object
- it creates the new object of the correct type (same as original)
- will make a bit-by-bit copy
- it is declared native, which means it is implemented in C/C++ so I haven't seen its source code
- But this doesn't mean your object can perform the clone!
- your class must implement the Cloneable interface
- this is a marker interface, as mentioned above
- if this is not done, clone() will throw a CloneNotSupportedException
- If you override the clone() method, its first statement must be super.clone()
- Cloning does not work correctly unless Object's clone() is invoked and completed
before any subclassed cloning action occurs
- This is because Object's clone will create the right kind of object before doing the bit-by-bit copy
- If your clone method creates the new object using your constructor instead of calling super.clone(),
then subclasses of your class may invoke your clone method through their super.clone(), and your clone will
create the wrong object type for your subclass!
- If your object contains only primitive values, Object's clone() method will do
- If your object contains references, things are not so simple...
- Object's clone method makes a shallow clone
- Because it is a bit-by-bit copy, references (pointers) are copied
- Copying the reference creates an alias.
- If the reference is to an immutable object (can't be modified), the alias is OK
- If the reference is to a mutable object, the alias is probably not what you want (the new object is unknowingly coupled to the existing one)
- If your object contains references to mutable objects, you probably want a deep clone
- requires you to write your own clone() method
- remember, it must start by calling super clone!
- for each mutable object, you need to make a copy and assign to your reference
- this means you might need its clone!
- could trigger recursive cloning
- In a nutshell, cloning must be implemented with great care. In fact JavaPractices.com says don't do it! They suggest alternatives.
[ C
SC 205 | Peter
Sanderson | Math Sciences server
| Math Sciences home page
| Otterbein ]
Last updated:
Peter Sanderson (PSanderson@otterbein.edu)