Implementation of Java Collections (cont.)

Download Report

Transcript Implementation of Java Collections (cont.)

Java Collection framework:
On concrete collections and their
implementation
1
Concrete collections in Java library
• ArrayList: indexed sequence that grows/shrinks dynamically
• LinkedList: ordered sequence that allows efficient insertions
and removal at any location
• HashSet: unordered collection that rejects duplicates
• TreeSet: sorted set
• EnumSet: set of enumerated type values (implements Set)
• LinkedHashSet: set that remembers the order in which elements
were inserted
• PriorityQueue: allows efficient removal of the smallest element
• HashMap: stores key/value associations
• TreeMap: map in which the keys are sorted
• EnumMap: keys belong to an enumerated type (impl. Map)
• LinkedHashMap: remembers the order in which added
• WeakHashMap: keys and entries that can be reclaimed by the
garbage collector if the keys are not used elsewhere
• IdentityHashMap: keys that are compared by ==, not equals
2
LinkedList: doubly-linked list
• LinkedList implements the List interface and extends
the AbstractCollection class (indirectly through
AbstractSequentialList)
• offers inexpensive operations to add into and remove
from the middle of a data structure
• LinkedList also gives (expensive) implementations
for using array indices: get (i), listIterator (i), etc.
• LinkedList provides methods to get, remove and
insert an element at the beginning and end
– these extra (see API) operations support efficient
stack, queue, or double-ended queue (deque)
handling; implements the Queue interface
3
LinkedList: doubly-linked list (cont.)
4
LinkedList: doubly-linked list (cont.)
List <E> list = new LinkedList <E> (aCollection)
list.addFirst (obj)
list.addLast (obj)
obj = list.getFirst ()
obj = list.getLast ()
obj = list.removeFirst ()
obj = list.removeLast ()
• list traversal is done by an implementation of
ListIterator
• a recursive list having itself as an element is not
permitted (but not checked)
5
Removing an element from a linked list
6
Adding an element to a linked list
7
ArrayList: sequentially allocated list
• the class ArrayList implements List
• internally, contains an Object [ ] array that is
automatically reallocated when needed
• methods to manipulate the array that stores the
elements: ensureCapacity (minCapacity), and
trimToSize ()
• gives efficient (O(1)) implementations for methods
with index positions, such as get (i), set (i, obj), etc.
• implements the marker interface RandomAccess
• note that ArrayList does not provide operations for
stack and queue handling (not a Queue)
• element traversals are made by an implementation of
ListIterator
8
Removing an element from an array
9
Implementation of Java Collections
• uses object-oriented mechanisms and patterns to
organize the services and the classes:
• encapsulation, inheritance, polymorphism;
– Template Method, Factory Method, Iterator,
Strategy, Proxy, etc.
• however, data structures are not organized into a
single-root class library
– some libraries handle maps uniformly as
collections of pair elements
• to support code reuse, the framework provides
abstract classes, e.g., AbstractCollection
• AbstractCollection implements Collection, leaving
operations, such as iterator () and size (), abstract
10
Relationships between framework classes
11
Implementation of Java Collections (cont.)
• the skeleton class either gives a method some
default definition, say, throwing an exception, or
implements it in terms of more basic operations
• e.g., utility routines, such as toString () and
addAll (aCollection), can be defined in terms of other
operations:
public class AbstractCollection <E>
implements Collection <E> {
...
public abstract Iterator<E> iterator ();
12
Implementation of Java Collections (cont.)
...
public boolean add (E obj) { // illegal by default
throw new UnsupportedOperationException ();
}
// a hypothetical implementation:
public boolean contains (Object obj) {
for (E element : this)
// calls iterator ()
if (element.equals (obj))
return true;
return false;
}
} // AbstractCollection <E>
13
Implementation of Java Collections (cont.)
• the abstract classes are meant to be used by
programmers wanting to extend the framework with
new implementations of data structures
• of course, must implement the missing abstract
methods to make default ones to work
• additionally, an implementation may override a
ready-made skeleton method to make it legitimate,
or to give it a more efficient implementation for a
specific concrete data structure
14
Error Handling
•
•
•
•
•
•
•
•
very thorough checks; uses unchecked exceptions
denied ops throw UnsupportedOperationException
unacceptable type throws ClassCastException
element constraint (e.g. range) violation throws
IllegalArgumentException
an accessed empty collection or exhausted iterator
throws NoSuchElementException
a null parameter (unless null is accepted as an
element) throws NullPointerException
invalid element index (< 0 or >= size ()) throws
IndexOutOfBoundsException
especially, constant views may throw
UnsupportedOperationException
15
Iterator error handling
• Iterator.remove () removes the last element visited
by next ()
• removal depends on the state of the iterator
– throws UnsupportedOperationException if the
remove operation is not supported, and
– throws IllegalStateException if the next method
has not yet been called
• generally, the behavior of an Iterator is unspecified
if the underlying collection is modified while the
iteration is in progress in any way other than by
calling the method remove
16
Iterator error handling (cont.)
• however, ListIterator.remove is guaranteed to throw
IllegalStateException if the list was structurally
modified (i.e., remove or add have been called) since
the last next or previous
• ListIterator.add (anObject) throws
– UnsupportedOperationException if the add
method is not supported by this list iterator
– ClassCastException (IllegalArgumentException) if
the class (or some other aspect) of the specified
element prevents it from being added to this list
• note that adding does not depend on the state of the
iterator (whether next or previous has been called)
17
Iterator error handling (cont.)
• the method set (newElement) replaces the last
element returned by last next or previous
• the update is done "in place", i.e., without
structurally modifying the data structure
• however, the method set () itself throws
IllegalStateException
– if neither next nor previous have been called, or
– if the list was structurally modified (remove or
add have been called) since the last next or
previous
18
Fail-Fast Feature
• iterators generally support the so-called fail-fast
feature
• this means that if the collection is modified after an
iterator is created, in any way except through the
iterator's own remove or add methods, an exception
is thrown
• only one iterator may be both reading and changing a
list, and multiple readers are allowed if they don't do
any structural modifications (so, set (obj) is OK)
• thus, in case of concurrent modification, the iterator
fails quickly, rather than risking arbitrary behaviour at
an undetermined time in the future
19
Fail-Fast Feature (cont.)
For example, consider the following code:
List<String> list = . . .;
ListIterator<String> iter1 = list.listIterator ();
ListIterator<String> iter2 = list.listIterator(list.size());
iter1.next ();
iter1.remove ();
iter2.next ();
// throws exception
• last call throws a ConcurrentModificationException
since iter2 detects that the list was modified
externally
20
Fail-Fast Feature: Summary
• an iterator throws ConcurrentModificationException,
if it founds that the data structure has been
structurally modified by other iterators or by
collection operations
• simple rule: attach as many reader iterators to a
collection as you like; alternatively, you can attach a
single iterator that can both read and write
– modification detection is achieved by a mutation
count values per each iterator and the collection
object
• note that here "ConcurrentModificationException"
doesn't mean to involve any multithreading
21