java collection: data structure framework
DESCRIPTION
Java Collection: Data structure framework. Background. collections store and organize objects for efficient access Java collections: traditional data structures implemented as an object-oriented framework currently only "basic data structures sufficient for most needs" - PowerPoint PPT PresentationTRANSCRIPT
1
Java Collection: Data structure framework
2
Background
• collections store and organize objects for efficient access
• Java collections: traditional data structures implemented as an object-oriented framework – currently only "basic data structures sufficient
for most needs" – sets, linked lists, arrays, and maps
• efficiency depends on organization and use – linked vs. sequential allocation, and hashing vs.
sorted search trees
3
Interfaces of the collections framework
4
Collection architecture
• the collections library utilizes heavily inheritance and polymorphism
• the library is implemented as a kind of (lightweight) framework, and it enables user-defined extensions
• separation of interfaces + their implementations: – Collection
• List implemented by ArrayList and LinkedList • Set implemented by HashSet and
LinkedHashSet – SortedSet implemented by TreeSet
5
Collection architecture (cont.)
• Map implemented by HashMap, IdentityHashMap, and LinkedHashMap – SortedMap implemented by TreeMap
• we have Iterable, Iterator and ListIterator interfaces – Iterable: provides the method iterator ()– Iterator: hasNext (), next (), and remove ()– ListIterator: add (), set (), hasPrevious (),
previous (), nextIndex (), etc..
• additionally, a set of abstract classes that provide skeletons for implementations– apply the Template Method pattern
6
Generic utility methods
• you can write utility methods that can operate on any kind of collection
public static <E> boolean contains (Collection <E> c, Object obj) {
for (E e : c) if (e.equals (obj) ) return true;
return false;
} • the above for statement is a short-hand notation for
. .for (it = c.iterator (); it.hasNext (); ) { e = it.next ();. .
7
Using object-oriented collections
• the idea: always use collections through interfaces, and separately create them as concrete collections:
Set <String> set = new HashSet <String> ();
set.add ("first");
set.add ("second");
int n = set.size (); // n is 2
assert set.contains ("first");
• you should always ask what is the most general class or interface that can do the required job
8
Design of Collection framework
• a built-in class library should satisfy many mutually conflicting requirements: – easy to learn and convenient to use– as general as possible: dynamic / flexible /
immutable, etc. structures – idiot-proof with complete run-time checks, and – as efficient as hand-coded algorithms
• fit some language limitations: – Java cannot express and enforce constness at
compile time – Java generics involves no run-time type info
9
Design of framework (cont.)
• the concrete implementations provide different performance and errors
• the interfaces abstract these differences away providing very general and concise interfaces
• the design makes compromises between practical requirements and pure conceptual modelling – for example, interfaces have so-called optional
operations, forbidden by specific implementations, e.g., Iterator.remove ()
– a called forbidden optional operation throws UnsupportedOperationException (unchecked)
– thus, constant views on collections are supported (only) by run-time checks
10
Design of framework (cont.)
• such refusal of inherited operations is clearly an is-a violation, at the conceptual level– the general object-oriented substitution principle:
"operation that expects an instance of a supertype must also accept an instance of a subtype" does not hold here
• such solutions are strongly discouraged by most object-oriented methodologies – you should (generally) avoid applying these
techniques in the design and interfaces of your own object-oriented applications
11
Overview: Collection
• expressed as hierarchically organized interfaces• Collection represents a "bag" (multiset) of values:
duplicates are (in principle) allowed – List is a sequentially ordered set of values – values in a List are ordered by position and can be
identified by integer indices (0..) • implemented as an array or as a linked list
– Set provides otherwise identical interface to Collection but allows no duplicates
– values in a Set are not necessarily ordered or sorted • SortedSet is sorted by comparison of element
values
12
Overview: Map
Map is an "associative table" of key-value pairs • insert key-value pair:
V oldValue = map.put (keyObject, newValue) • get value, or null if the key is not found:
value = map.get (keyObject)
For example,
Map <String, V> map = new HashMap <String, V> ();
map.put ("first", x);
map.put ("second", y);
map.put ("third", x);
assert map.get ("first").equals (x);
V v = map.remove ("first");
13
Overview: SortedMap
• SortedMap is sorted by comparison of element values – either by natural order given by the object class,
or by a separate comparison method • must either implement the Comparable
interface, or use a Comparator object
14
Views into collections
• in the Java data structure library, Maps are not considered to be Collections
• however, views use Collection interfaces • aMap.entrySet () returns a Set of Map.Entries
– Map.Entry provides methods: getKey (), getValue (), and setValue (v)
– however, no getEntry (key) is provided (vs. C++ STL) - Entry is an interface, only
• note that collection views are an application of the Proxy design pattern [Gamma et al, p. 207]
15
Views into collections (cont.)
• collection methods are not by default thread-safe, i.e., not synchronized for concurrent access – this avoids unnecessary overheads
• interfaces do not determine whether implemented methods are synchronized or not (as usual)
• thread-safe collection handling is supported by separate synchronized views, created by a call:
Collections.synchronizedX (X c),
where X can be Collection, List, Map, Set, SortedMap, or SortedSet
• note: class Collections is not interface Collection
16
Views into collections (cont.)
• similarly, a constant collection may be created by a call: – Collections.unmodifiableX (X c)
• framework also offers "generic" (C++ STL like) algorithms: searching and sorting, etc.
• the old "legacy" classes (Vector, Hashtable, etc.) have been fitted into the framework – however, the legacy classes are synchronized,
and thus involve a substantial overhead
17
Collections and iterators
• all Collection objects and their iterators show similar general behaviour:
// implementation-dependency here only:
Collection <E> coll = new LinkedList <E> ();
// use through abstract interface:
coll.add (element); ...
Iterator <E> iterator = coll.iterator ();
while (iterator.hasNext ()) {
E element = iter.next ();
// .. do something with element
} ...
18
Using iterators
• the method iterator () returns an implementation of Iterator that can be used to traverse and possibly modify the collection:
while (iter.hasNext ()) . . .
obj = iter.next ()
obj = iter.remove ()
• of course, accessing past the already reached end of a list is considered a programming error – if hasNext () returns false, then calling next () will
throw (unchecked) NoSuchElementException
19
Advancing an iterator
20
Using iterators (cont.)
• iterator represents a position between two elements in the data structure – note: C++ containers use a different strategy:
iterators are (abstract) pointers to elements
• an iterator can provide a way to remove an element related to that position – iterator.remove () removes the element returned
by the last next () – note that next () must be called (at least once)
before each removal
21
Collection services
• a sample of Collection methods:
Iterator iterator ()
int size ();
boolean isEmpty ()
boolean contains (Object v)
boolean containsAll (Collection <?> c)
boolean equals (Object other)
boolean add (E element)
boolean addAll (Collection <? extends E> c)
boolean remove (Object element)
22
Collection services (cont.)
. . .
boolean removeAll (Collection <?> c)
void clear ()
boolean retainAll (Collection <?> c)
Object [ ] toArray ()
<T> T [ ] toArray(T [ ] a) // may allocate bigger
• note that
E [ ] array = ...
List <E> list = Arrays.asList (array) // a proxy
can be used to create a fixed-size list backed by the specified array (changes "write through" to the array)
23
Collection services (cont.)
• many operations (add, etc.) return a boolean value to indicate whether the operation really modified the data structure – e.g., remove (obj) returns true if a maching
(equals) object was removed – note that iterator's remove returns void (as does
ListIterator)
• for a more detailed description of java.util.Collection services, see the API or the textbook, pp. 85 - 93
24
The List Interface
• the List interface defines a sequentially ordered set of values:
// pos means position index 0..size
list.add (pos, obj)
list.addAll (pos, aCollection)
list.get (pos)
list.set (pos, obj)
obj = list.remove (pos)
ListIterator <E> iter = list.listIterator ()
ListIterator <E> iter = list.listIterator (fromPos)
25
The List Interface
. . .
pos = list.indexOf (obj)
pos = list.lastIndexOf (obj)
sublist = list.subList (from, beyond) // get view
• subList creates a proxy object that– is backed by this list, so non-structural changes
are reflected in the original list, and vice-versa – supports all of the optional list operations
supported by the backing list – becomes undefined if the backing list is
structurally modified in other way than via the proxy
26
ListIterator
• the related ListIterator traverses the elements in order, possibly also modifying the data structure
iter = list.listIterator (fromPos);
• backwards traversing, index handling, and insertion of values:
while (iter.hasPrevious ()) . . .
obj = iter.previous ()
iter.add (obj)
iter.set (obj)
pos = iter.nextIndex ()
pos = iter.previousIndex ()
27
ListIterator (cont.)• ListIterator represents an indexed position within a
sequential data structure – the iterator represents a position between two
elements; or at beginning before all others (0); or at end, after all elements (size ())
• the method add (v) inserts the new element at the current position, i.e., before the next element – if previous () is called after add, the new element
is returned – so, calling add repeatedly puts elements in the
exact order they are given – increases by one nextIndex and previousIndex
• note that the Iterator interface allowed only a removal of an element (optional)