Tuesday 21 March 2017

The Collections Framework, Collections Overview & The Collection Interfaces - Java Tutorials

The Collections Framework

The java.util package contains one of Java’s most powerful subsystems: collections. Collections were added by the initial release of Java 2, and enhanced by Java 2, version 1.4. A collection is a group of objects. The addition of collections caused fundamental alterations in the structure and architecture of many elements in java.util. It also expanded the domain of tasks to which the package can be applied. Collections are a state-of-the-art technology that merits close attention by all Java programmers.

In addition to collections, java.util contains a wide assortment of classes and interfaces that support a broad range of functionality. These classes and interfaces are used throughout the core Java packages and, of course, are also available for use in programs that you write. Their applications include generating pseudorandom numbers, manipulating date and time, observing events, manipulating sets of bits, and tokenizing strings. Because of its many features, java.util is one of Java’s most widely used packages. The java.util classes are listed here.

AbstractCollection (Java 2)
EventObject 
PropertyResourceBundle
AbstractList (Java 2) 
GregorianCalendar 
Random
AbstractMap (Java 2) 
HashMap (Java 2) 
ResourceBundle
AbstractSequentialList (Java 2) 
HashSet (Java 2) 
SimpleTimeZone
AbstractSet (Java 2) 
Hashtable 
Stack
ArrayList (Java 2) 
IdentityHashMap (Java 2, v1.4) 
StringTokenizer
Arrays (Java 2) 
LinkedHashMap (Java 2, v1.4) 
Timer (Java 2, v1.3)
BitSet 
LinkedHashSet (Java 2, v1.4) 
TimerTask (Java 2, v1.3)
Calendar 
LinkedList (Java 2) 
TimeZone
Collections (Java 2) 
ListResourceBundle 
TreeMap (Java 2)
Currency (Java 2, v1.4) 
Locale 
TreeSet (Java 2)
Date 
Observable 
Vector
Dictionary 
Properties 
WeakHashMap (Java 2)
EventListenerProxy (Java 2, v1.4) 
PropertyPermission (Java 2)

java.util defines the following interfaces. Notice that most were added by Java 2.

Collection (Java 2) 
List (Java 2) 
RandomAccess (Java 2, v1.4)
Comparator (Java 2) 
ListIterator (Java 2) 
Set (Java 2)
Enumeration 
Map (Java 2) 
SortedMap (Java 2)
EventListener 
Map.Entry (Java 2) 
SortedSet (Java 2)
Iterator (Java 2) 
Observer

The ResourceBundle, ListResourceBundle, and PropertyResourceBundle classes aid in the internationalization of large programs with many locale-specific resources. These classes are not examined here. PropertyPermission, which allows you to grant a read/write permission to a system property, is also beyond the scope of this book. EventObject, EventListener, and EventListenerProxy are described in Chapter 20. The remaining classes and interfaces are examined in detail.

Because java.util is quite large, its description is broken into two chapters. This chapter examines those members of java.util that relate to collections of objects. Chapter 16 discusses the other classes and interfaces.




Collections Overview

The Java collections framework standardizes the way in which groups of objects are handled by your programs. Prior to Java 2, Java provided ad hoc classes such as Dictionary, Vector, Stack, and Properties to store and manipulate groups of objects. Although these classes were quite useful, they lacked a central, unifying theme. Thus, the way that you used Vector was different from the way that you used Properties, for example. Also, the previous, ad hoc approach was not designed to be easily extensible or adaptable. Collections are an answer to these (and other) problems.

The collections framework was designed to meet several goals. First, the framework had to be high-performance. The implementations for the fundamental collections (dynamic arrays, linked lists, trees, and hash tables) are highly efficient. You seldom, if ever, need to code one of these “data engines” manually. Second, the framework had to allow different types of collections to work in a similar manner and with a high degree of interoperability. Third, extending and/or adapting a collection had to be easy. Toward this end, the entire collections framework is designed around a set of standard interfaces. Several standard implementations (such as LinkedList, HashSet, and TreeSet) of these interfaces are provided that you may use as-is. You may also implement your own collection, if you choose. Various special-purpose implementations are created for your convenience, and some partial implementations are provided that make creating your own collection class easier. Finally, mechanisms were added that allow the integration of standard arrays into the collections framework.

Algorithms are another important part of the collection mechanism. Algorithms operate on collections and are defined as static methods within the Collections class. Thus, they are available for all collections. Each collection class need not implement its own versions. The algorithms provide a standard means of manipulating collections.

Another item created by the collections framework is the Iterator interface. An iterator gives you a general-purpose, standardized way of accessing the elements within a collection, one at a time. Thus, an iterator provides a means of enumerating the contents of a collection. Because each collection implements Iterator, the elements of any collection class can be accessed through the methods defined by Iterator. Thus, with only small changes, the code that cycles through a set can also be used to cycle through a list, for example.

In addition to collections, the framework defines several map interfaces and classes. Maps store key/value pairs. Although maps are not “collections” in the proper use of the term, they are fully integrated with collections. In the language of the collections framework, you can obtain a collection-view of a map. Such a view contains the elements from the map stored in a collection. Thus, you can process the contents of a map as a collection, if you choose.

The collection mechanism was retrofitted to some of the original classes defined by java.util so that they too could be integrated into the new system. It is important to understand that although the addition of collections altered the architecture of many of the original utility classes, it did not cause the deprecation of any. Collections simply provide a better way of doing several things.

One last thing: If you are familiar with C++, then you will find it helpful to know that the Java collections technology is similar in spirit to the Standard Template Library (STL) defined by C++. What C++ calls a container, Java calls a collection.




The Collection Interfaces

The collections framework defines several interfaces. This section provides an overview of each interface. Beginning with the collection interfaces is necessary because they determine the fundamental nature of the collection classes. Put differently, the concrete classes simply provide different implementations of the standard interfaces. The interfaces that underpin collections are summarized in the following table:

Collection:  Enables you to work with groups of objects; it is at the top of the collections hierarchy

List:  Extends Collection to handle sequences (lists of objects)

Set:  Extends Collection to handle sets, which must contain unique elements

SortedSet:  Extends Set to handle sorted sets

In addition to the collection interfaces, collections also use the Comparator, Iterator, ListIterator and RandomAccess interfaces, which are described in depth later in this chapter. Briefly, Comparator defines how two objects are compared; Iterator and ListIterator enumerate the objects within a collection. By implementing RandomAccess, a list indicates that it supports efficient, random access to its elements.

To provide the greatest flexibility in their use, the collection interfaces allow some methods to be optional. The optional methods enable you to modify the contents of a collection. Collections that support these methods are called modifiable. Collections that do not allow their contents to be changed are called unmodifiable. If an attempt is made to use one of these methods on an unmodifiable collection, an UnsupportedOperationException is thrown. All the built-in collections are modifiable. The following sections examine the collection interfaces.


The Collection Interface

The Collection interface is the foundation upon which the collections framework is built. It declares the core methods that all collections will have. These methods are summarized in Table 15-1. Because all collections implement Collection, familiarity with its methods is necessary for a clear understanding of the framework. Several of these methods can throw an UnsupportedOperationException. As explained, this occurs if a collection cannot be modified. A ClassCastException is generated when one object is incompatible with another, such as when an attempt is made to add an incompatible object to a collection.


The Methods Defined by Collection

boolean add(Object obj):   Adds obj to the invoking collection. Returns true if obj was added to the collection. Returns false if obj is already a member of the collection, or if the collection does not allow duplicates.

boolean addAll(Collection c):   Adds all the elements of c to the invoking collection. Returns true if the operation succeeded (i.e., the elements were added). Otherwise, returns false.

void clear( ):  Removes all elements from the invoking collection.

boolean contains(Object obj):  Returns true if obj is an element of the invoking collection. Otherwise, returns false.

boolean containsAll(Collection c):  Returns true if the invoking collection contains all elements of c. Otherwise, returns false.

boolean equals(Object obj):  Returns true if the invoking collection and obj are equal. Otherwise, returns false.

int hashCode( ):  Returns the hash code for the invoking collection.

boolean isEmpty( ):  Returns true if the invoking collection is empty. Otherwise, returns false.

Iterator iterator( ):  Returns an iterator for the invoking collection.

boolean remove(Object obj):  Removes one instance of obj from the invoking collection. Returns true if the element was removed. Otherwise, returns false.

boolean removeAll(Collection c):  Removes all elements of c from the invoking collection. Returns true if the collection changed (i.e., elements were removed). Otherwise, returns false.

boolean retainAll(Collection c):  Removes all elements from the invoking collection except those in c. Returns true if the collection changed (i.e., elements were removed). Otherwise, returns false.

int size( ):  Returns the number of elements held in the invoking collection.

Object[ ] toArray( ):  Returns an array that contains all the elements stored in the invoking collection. The array elements are copies of the collection elements.

Object[ ] toArray(Object array[ ]):  Returns an array containing only those collection elements whose type matches that of array. The array elements are copies of the collection elements. If the size of array equals the number of matching elements, these are returned in array. If the size of array is less than the number of matching elements, a new array of the necessary size is allocated and returned. If the size of array is greater than the number of matching elements, the array element following the last collection element is set to null. An ArrayStoreException is thrown if any collection element has a type that is not a subtype of array.


Objects are added to a collection by calling add( ). Notice that add( ) takes an argument of type Object. Because Object is a superclass of all classes, any type of object may be stored in a collection. However, primitive types may not. For example, a collection cannot directly store values of type int, char, double, and so forth. Of course, if you want to store such objects, you can also use one of the primitive type wrappers described in Chapter 14. You can add the entire contents of one collection to another by calling addAll( ).

You can remove an object by using remove( ). To remove a group of objects, call removeAll( ). You can remove all elements except those of a specified group by calling retainAll( ). To empty a collection, call clear( ).

You can determine whether a collection contains a specific object by calling contains( ). To determine whether one collection contains all the members of another, call containsAll( ). You can determine when a collection is empty by calling isEmpty( ). The number of elements currently held in a collection can be determined by calling size( ).

The toArray( ) method returns an array that contains the elements stored in the invoking collection. This method is more important than it might at first seem. Often, processing the contents of a collection by using array-like syntax is advantageous. By providing a pathway between collections and arrays, you can have the best of both worlds.

Two collections can be compared for equality by calling equals( ). The precise meaning of “equality” may differ from collection to collection. For example, you can implement equals( ) so that it compares the values of elements stored in the collection. Alternatively, equals( ) can compare references to those elements.

One more very important method is iterator( ), which returns an iterator to a collection. As you will see, iterators are crucial to successful programming when using the collections framework.


The List Interface

The List interface extends Collection and declares the behavior of a collection that stores a sequence of elements. Elements can be inserted or accessed by their position in the list, using a zero-based index. A list may contain duplicate elements.

In addition to the methods defined by Collection, List defines some of its own, which are summarized in Table 15-2. Note again that several of these methods will throw an UnsupportedOperationException if the collection cannot be modified, and a ClassCastException is generated when one object is incompatible with another, such as when an attempt is made to add an incompatible object to a collection.

To the versions of add( ) and addAll( ) defined by Collection, List adds the methods add(int, Object) and addAll(int, Collection). These methods insert elements at the specified index. Also, the semantics of add(Object) and addAll(Collection) defined by Collection are changed by List so that they add elements to the end of the list.

To obtain the object stored at a specific location, call get( ) with the index of the object. To assign a value to an element in the list, call set( ), specifying the index of the object to be changed. To find the index of an object, use indexOf( ) or lastIndexOf( ).


The Methods Defined by List

void add(int index, Object obj):  Inserts obj into the invoking list at the index passed in index. Any preexisting elements at or beyond the point of insertion are shifted up. Thus, no elements are overwritten.

boolean addAll(int index, Collection c):  Inserts all elements of c into the invoking list at the index passed in index. Any preexisting elements at or beyond the point of insertion are shifted up. Thus, no elements are overwritten. Returns true if the invoking list changes and returns false otherwise.

Object get(int index):  Returns the object stored at the specified index within the invoking collection.

int indexOf(Object obj):  Returns the index of the first instance of obj in the invoking list. If obj is not an element of the list, –1 is returned.

int lastIndexOf(Object obj):  Returns the index of the last instance of obj in the invoking list. If obj is not an element of the list, –1 is returned.

ListIterator listIterator( ):  Returns an iterator to the start of the invoking list.

ListIterator listIterator(int index):  Returns an iterator to the invoking list that begins at the specified index.

Object remove(int index):  Removes the element at position index from the invoking list and returns the deleted element. The resulting list is compacted. That is, the indexes of subsequent elements are decremented by one.

Object set(int index, Object obj):  Assigns obj to the location specified by index within the invoking list.

List subList(int start, int end):  Returns a list that includes elements from start to end–1 in the invoking list. Elements in the returned list are also referenced by the invoking object.


You can obtain a sublist of a list by calling subList( ), specifying the beginning and ending indexes of the sublist. As you can imagine, subList( ) makes list processing quite convenient.


The Set Interface

The Set interface defines a set. It extends Collection and declares the behavior of a collection that does not allow duplicate elements. Therefore, the add( ) method returns false if an attempt is made to add duplicate elements to a set. It does not define any additional methods of its own.


The SortedSet Interface

The SortedSet interface extends Set and declares the behavior of a set sorted in ascending order. In addition to those methods defined by Set, the SortedSet interface declares the methods summarized in Table 15-3. Several methods throw a NoSuchElementException when no items are contained in the invoking set. A ClassCastException is thrown when an object is incompatible with the elements in a set. A NullPointerException is thrown if an attempt is made to use a null object and null is not allowed in the set.

SortedSet defines several methods that make set processing more convenient. To obtain the first object in the set, call first( ). To get the last element, use last( ). You can obtain a subset of a sorted set by calling subSet( ), specifying the first and last object in the set. If you need the subset that starts with the first element in the set, use headSet( ). If you want the subset that ends the set, use tailSet( ).


The Methods Defined by SortedSet

Comparator comparator( ):  Returns the invoking sorted set’s comparator. If the natural ordering is used for this set, null is returned.

Object first( ):  Returns the first element in the invoking sorted set.

SortedSet headSet(Object end):  Returns a SortedSet containing those elements less than end that are
contained in the invoking sorted set. Elements in the returned sorted set are also referenced by the invoking xsorted set.

Object last( ):  Returns the last element in the invoking sorted set.

SortedSet subSet(Object start, Object end):  Returns a SortedSet that includes those elements between start and end–1. Elements in the returned collection are also referenced by the invoking object.

SortedSet tailSet(Object start):  Returns a SortedSet that contains those elements greater than or equal to start that are contained in the sorted set. Elements in the returned set are also referenced by the invoking object.

No comments:

Post a Comment