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