1 Collection architecture (cont.) Generic utility methods Map - - PowerPoint PPT Presentation

1
SMART_READER_LITE
LIVE PREVIEW

1 Collection architecture (cont.) Generic utility methods Map - - PowerPoint PPT Presentation

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


slide-1
SLIDE 1

1

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

slide-2
SLIDE 2

2

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

slide-3
SLIDE 3

3

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

  • perations, 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
  • bject-oriented methodologies

– you should (generally) avoid applying these techniques in the design and interfaces of your

  • wn 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");

slide-4
SLIDE 4

4

13

Overview: SortedMap

  • SortedMap is sorted by comparison of element

values – either by natural order given by the object class,

  • r 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

slide-5
SLIDE 5

5

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 ()) . . .

  • bj = iter.next ()
  • bj = iter.remove ()
  • of course, accessing past the already reached end
  • f 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

slide-6
SLIDE 6

6

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
  • f values:

// pos means position index 0..size list.add (pos, obj) list.addAll (pos, aCollection) list.get (pos) list.set (pos, obj)

  • bj = list.remove (pos)

ListIterator <E> iter = list.listIterator () ListIterator <E> iter = list.listIterator (fromPos)

slide-7
SLIDE 7

7

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
  • rder, possibly also modifying the data structure

iter = list.listIterator (fromPos);

  • backwards traversing, index handling, and insertion
  • f values:

while (iter.hasPrevious ()) . . .

  • bj = 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);

  • r 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)