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 ) • Java Collection framework: LinkedHashSet: set that remembers the order in which elements • were inserted On concrete collections and their PriorityQueue: allows efficient removal of the smallest element • implementation • 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 1 2 LinkedList: doubly-linked list LinkedList: doubly-linked list (cont.) • 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 4 1
LinkedList: doubly-linked list (cont.) Removing an element from a linked list 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 6 Adding an element to a linked list 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 7 8 2
Implementation of Java Collections Removing an element from an array • 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 9 10 Implementation of Java Collections (cont.) Relationships between framework classes • 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 (); 11 12 3
Implementation of Java Collections (cont.) Implementation of Java Collections (cont.) . . . public boolean add (E obj) { // illegal by default • the abstract classes are meant to be used by throw new UnsupportedOperationException (); programmers wanting to extend the framework with } new implementations of data structures // hypothetical implementation: • of course, must implement the missing abstract public boolean contains (Object obj) { methods to make default ones to work for (E element : this) // calls iterator () • additionally, an implementation may override a if (element.equals (obj)) ready-made skeleton method to make it legitimate, return true; or to give it a more efficient implementation for a specific concrete data structure return false; } } // AbstractCollection <E> 13 14 Error Handling Iterator error handling • very thorough checks; uses unchecked exceptions • Iterator . remove () removes the last element visited • denied ops throw UnsupportedOperationException by next () • unacceptable type throws ClassCastException • removal depends on the state of the iterator • element constraint (e.g. range) violation throws – throws UnsupportedOperationException if the IllegalArgumentException remove operation is not supported, and • an accessed empty collection or exhausted iterator – throws IllegalStateException if the next method throws NoSuchElementException has not yet been called • a null parameter (unless null is accepted as an element) throws NullPointerException • generally, the behavior of an Iterator is unspecified if the underlying collection is modified while the • invalid element index (< 0 or >= size ()) throws iteration is in progress in any way other than by IndexOutOfBoundsException calling the method remove • especially, constant views may throw UnsupportedOperationException 15 16 4
Iterator error handling (cont.) Iterator error handling (cont.) • however, ListIterator.remove is guaranteed to throw IllegalStateException if the list was structurally • the method set ( newElement ) replaces the last modified (i.e., remove or add have been called) since element returned by last next or previous the last next or previous • the update is done "in place", i.e., without structurally modifying the data structure • ListIterator.add ( anObject ) throws • however, the method set () itself throws – UnsupportedOperationException if the add IllegalStateException method is not supported by this list iterator – if neither next nor previous have been called, or – ClassCastException ( IllegalArgumentException ) if – if the list was structurally modified ( remove or the class (or some other aspect) of the specified add have been called) since the last next or element prevents it from being added to this list previous • note that adding does not depend on the state of the iterator (whether next or previous has been called) 17 18 Fail-Fast Feature Fail-Fast Feature (cont.) • iterators generally support the so-called fail-fast feature For example, consider the following code: • this means that if the collection is modified after an List<String> list = . . .; iterator is created, in any way except through the ListIterator<String> iter1 = list.listIterator (); iterator's own remove or add methods, an exception is thrown ListIterator<String> iter2 = list.listIterator(list.size()); • only one iterator may be both reading and changing a iter1.next (); list, and multiple readers are allowed if they don't do iter1.remove (); any structural modifications (so, set ( obj ) is OK) iter2.next (); // throws exception • thus, in case of concurrent modification, the iterator fails quickly, rather than risking arbitrary behaviour • last call throws a ConcurrentModificationException at an undetermined time in the future since iter2 detects that the list was modified externally 19 20 5
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 6
Recommend
More recommend