Title: Utility and Collection Classes
1Utility and Collection Classes
- CSC 313 Course Notes by
- Linda M. Hicks
2Utility Classes
- In this chapter you will learn
- What the Enumeration interface is used for
- What a Vector is and how to use Vector objects in
your programs - How to manage Vector objects so that storing and
retrieving elements is type safe - What a Stack is and how you use it
- What facilities the Random class provides
- How to create and use Date objects
3Utility Classes
- In this chapter you will learn
- How you store and retrieve objects in a hash
table represented by a Hashtable object - How you can generate hash codes for your own
class objects - How to use the Observable class and the Observer
interface to communicate between objects - What facilities the Random class provides
- How to create and use Date objects
4Java.util Package
Key
5The java.util Package
- The package java.util contains a number of
useful classes and interfaces. Some of the
classes and interfaces in java.util include - The Hashtable class for implementing hashtables,
or associative arrays. - The Vector class, which supports variable-length
arrays. - The Enumeration interface for iterating through a
collection of elements.
6The java.util Package Cont.
- The StringTokenizer class for parsing strings
into distinct tokens separated by delimiter
characters. - The EventObject class and the EventListener
interface, which form the basis of the AWT event
model in Java 1.1. - The Calendar and TimeZone classes in Java. These
classes interpret the value of a Date object in
the context of a particular calendar system.
7Utility Classes
- The utility classes are primarily a set of tools
for storing and managing data in memory in a
variety of ways, plus some other odds and ends. - If you want an array that automatically expands
to accommodate however many objects you throw
into it, or you need to be able to store and
retrieve an object based on what it is, rather
than using an index or a sequence number, then
look no further. - You get all this and more in the java.util
package.
8Utility Classes
9The Enumeration Interface
- An enumeration is a collection of objects that
can be retrieved serially-traveling in one
direction through the data. Since an enumeration
is intended for one time use, it's usually
created on demand by a collection of elements,
such as a Vector or a Hashtable. You just ask the
collection to create a new Enumeration object
whenever you want to iterate through the objects
you have stored in that collection. - The Enumeration interface only declares two
methods
10The Enumeration Interface
- The Enumeration interface only declares two
methods
11Enumeration Interface nextElement()
- Because the nextElement() method returns an
object of type Object, it can return any type of
object and is thus completely general. - However, when you retrieve an element, you'll
usually want to cast the reference returned to
the original type of the object. - We will see how you use these methods to retrieve
objects when we get into using Vector objects.
12The Vector Class
- The Vector class defines a collection of elements
of type Object that works like an array, but with
the additional feature that it can grow itself
automatically when you need more capacity. - Because it stores elements of type Object, and
Object is a superclass of every object, you can
store any type of object in a Vector. - Keep in mind that all the storage classes you're
about to encounter hold object references.
13Vector Constructors
- There are three constructors for the Vector
class - Vector ()
- Vector (int capacity)
- Vector (int capacity, int increment)
- Where capacity specifies than in initial
number of elements for which to reserve space,
and increment indicates how much the capacity
should be incremented every time the Vector must
grow.
14Vector Class Size Capacity
15Vector Example Program
- import java.io.
- import java.util.
- class vectorEx
-
- static BufferedReader keyboard new
- BufferedReader(new InputStreamReader(S
ystem.in)) - static PrintWriter screen new
PrintWriter(System.out, true) - static public void main(String args) throws
IOException -
- final int INITIAL_SIZE 4
- Vector wordList new Vector(INITIAL_SIZE)
- int sizeOfVector, capOfVector, midIndex
- String word
- screen.println("Input single words, one per
line, type EXIT to - quit\n")
-
16Vector Example Program
- screen.print("Word? ") screen.flush()
- word keyboard.readLine()
- while (! word.equals("EXIT"))
-
- wordList.addElement(word)
- screen.println ( "capacity "
wordList.capacity() " size " - wordList.size() " index "
- wordList.indexOf(word) "
contents word ) -
- screen.print ("Word? ") screen.flush()
- word keyboard.readLine()
-
-
17Vector Example Program
- screen.println("\nsize of vector "
wordList.size() ) - screen.println("capacity of vector "
wordList.capacity()) - screen.println("first element "
wordList.firstElement()) - screen.println("last element "
wordList.lastElement()) -
- midIndex wordList.size() / 2
- screen.print ("middle element at index "
midIndex " is " - wordList.elementAt(midIndex))
- wordList.trimToSize()
- capOfVector wordList.capacity()
- screen.println("\ntrimmed size capacity "
capOfVector) -
- screen.println("\nContents of Vector")
- for (int index0 index ! capOfVector
index) -
- screen.print( wordList.elementAt(index)
" ") - screen.flush()
-
18Example Program Output
- Input single words, one per line, type EXIT to
quit - Word? lime capacity 4 size 1 index 0
contents lime - Word? pear capacity 4 size 2 index 1
contents pear - Word? apple capacity 4 size 3 index 2
contents apple - Word? grape capacity 4 size 4 index 3
contents grape - Word? lemon capacity 8 size 5 index 4
contents lemon - Word? peach capacity 8 size 6 index 5
contents peach - Word? mango capacity 8 size 7 index 6
contents mango - Word? cherry capacity 8 size 8 index 7
contents cherry - Word? orange capacity 16 size 9 index 8
contents orange - Word? banana capacity 16 size 10 index 9
contents banana - Word? tangerine capacity 16 size 11 index 10
contents tangerine - Word? pineapple capacity 16 size 12 index 11
contents pineapple - Word? blueberry capacity 16 size 13 index 12
contents blueberry - Word? raspberry capacity 16 size 14 index 13
contents raspberry - Word? watermelon capacity 16 size 15 index 14
contents watermelon - Word? cantaloupe capacity 16 size 16 index 15
contents cantaloupe - Word? strawberry capacity 32 size 17 index 16
contents strawberry
19Example Program Output
- Word? EXIT
- size of vector 18
- capacity of vector 32
- first element lime
- last element grapefruit
- middle element at index 9 is banana
- trimmed size capacity 18
-
- Contents of Vector
- lime pear apple grape lemon peach mango
cherry orange banana tangerine pineapple
blueberry raspberry watermelon cantaloupe
strawberry grapefruit
20Accessing Elements through an Enumeration
- We can replace the for loop in this program
- for (int index0 index ! capOfVector index)
-
- screen.print( wordList.elementAt(index) "
") - screen.flush()
-
- with the following enumerator
21Accessing Elements through an Enumeration
- // create an enumeration object to retrieve all
- // elements stored in vector.
- Enumeration theData wordList.elements()
- while (theData.hasMoreElements() )
-
- String theWord (String) theData.nextElement()
- System.out.println (theWord)
- screen.flush()
-
22Accessing Elements through an Enumeration
- Enumeration theData wordList.elements()
- The method elements() returns all the elements
in the Vector object, wordList, as an Enumeration
object, so you can now process them serially
using the methods declared in the Enumeration
interface. - while (theData.hasMoreElements() )
- When we've retrieved the last element from
the Enumeration, the method hasMoreElements()
will return false and the loop will end.
23Removing items from a Vector
- Removing items by position
- You can remove the reference at a particular
index position by calling the removeElementAt()
method with the index position of the object as
the argument. For example, - wordList.removeElementAt(3)
- will remove the fourth reference from wordList.
The references following this will now be at
index positions that are one less than they were
before, so that what was previously the fifth
object reference will now be at index position 3.
- Of course, the index value that you specify must
be legal for the Vector on which you're
operating, meaning greater than or equal to 0 and
less than its size(), otherwise an exception will
be thrown.
24Removing items from a Vector
- Removing items by reference
- Sometimes you'll want to remove a particular
reference, rather than the reference at a given
index. If you know what the object is that you
want to remove, you can use the removeElement()
method to delete it - boolean deleted wordList.removeElement(aWord)
- This will search the Vector, wordList, from the
beginning to find the reference to the object
aWord, and remove its first occurrence. If the
object is found and removed, the method returns
true, otherwise it returns false.
25Removing all items from Vector
- If you want to discard all the elements in a
Vector, you can use the removeAllElements()
method to empty the Vector in all at once - wordList.removeAllElements() // Dump the whole
lot
26Searching a Vector
- You can get the index position of an object
stored in a Vector by passing the object as an
argument to the method indexOf(). For example,
the statement, - int position wordList.indexOf(aWord)
- will search the Vector from the beginning for the
object aWord. The variable position will either
contain the index of the first reference to the
object in wordList, or -1 if the object isn't
found.
27Searching a Vector
- You have another version of the method indexOf()
available that accepts a second argument which is
an index position where the search for the object
should begin. - The main use for this arises when an object can
be referenced more than once in a Vector. You can
use the method to recover all occurrences of any
particular object, as follows
28Searching a Vector
- int position 0 // Search s
tarting index - while(positionltwordList.size() ) // Search with
a valid index -
- position transactions.indexOf
(aTransaction, position) - // Find next
- if (position -1) // If object no
t found... - break // ...end t
he loop - // Code to process the object in some way...
- position // Search from t
he next element -
-
29Searching a Vector
The while loop will continue as long as the
method indexOf() returns a valid index value and
the index doesn't get incremented beyond the end
of the Vector.
30Stack Storage
31Stack Storage
32Stack Constructor
- The only constructor for a Stack object is the
default constructor. - This will call the default constructor for the
base class, Vector, so you'll always get an
initial capacity for 10 objects, but since it's
basically a Vector, it will grow automatically in
the same way.
33Hash Table Storage
- A hash table, sometimes referred to as a map, is
a way of storing data that minimizes the need for
searching when you want to get an object back. - Each object is associated with a key which is
used to determine where to store the reference to
the object, and both the key and the object are
stored in the hash table. - Given a key, you can always go more or less
directly to the object that has been stored in a
hash table based on the key.
34Hash Table Storage
- In Java, hash tables are implemented by the class
Hashtable. - The keys used to store objects in a Hashtable
object are objects too, but the object that you
use as a key doesn't have to be the same as the
object that you're storing-indeed it usually
won't be. - For example, you could use a String object
containing a name as a key, for a Person object,
which would typically contain all kinds of other
information in addition to the name. If you know
the name for a Person object, you can immediately
retrieve that object by just supplying the name
as the key.
35The Hashing Process
- It's helpful to understand how the storage
mechanism works for a hash table. A Hashtable
object sets aside an array in which it will store
key and object pairs. - The index to this array, referred to as a hash
value, is produced from the key object by a
process known as hashing. - This uses the hashCode() method for the object
that's used as a key.
36The Hashing Process
- Note that each key doesn't have to result in a
unique hash value. When two or more different
keys produce the same hash value, it's called a
collision. - The Hashtable object is able to deal with
collisions by hooking the objects that share the
same hash value together in a linked list, as
shown below. For the sake of simplicity, the
diagram only shows the objects stored in the
table, but the key for each object is also
stored.
37The Hashing Process
38The Hashing Process
39The Hashing Process
- Generally, the better the uniqueness of the hash
values, the more efficient the operation of the
hash table is going to be. - When you access one of the objects that share a
common hash value, it will involve a serial
search of the list of keys corresponding to that
hash value. - The price of reducing the possibility of
collisions in a hash table is having plenty of
empty space in the table. - The class Object defines the method hashCode() so
any object can be used as a key, and it will hash
by default, but the method as it is currently
implemented in Object in Java 1.1 isn't ideal.
40The Hashing Process
- Since it uses the address where an object is
stored to produce the hash value, distinct
objects will always produce different hash
values. This is a plus because it is more likely
that a unique hash value will be produced for
each key. The huge minus is that objects which
use this default behavior and that are distinct,
but have identical contents, will produce
different hash values. - The effect of this is disastrous if you use this
default for objects of your own classes that
you're using as keys. - In this case, an object stored in a hash table
can never be retrieved using an object for a key
that is distinct from the original key object,
even though it may be identical in all other
respects.
41Using your own Class Objects as Keys
- For objects of one of your own classes to be
usable as keys in a hash table, you must
implement two methods in the class the equals()
method which accepts an object of the same class
as an argument, and returns a boolean value and
hashCode() which returns the hash value for the
object as type int. You'll be overriding the
versions of these methods that are inherited from
the class Object.
42Hashtable Constructors
43Storing and Retrieving Objects
44Hashtable
- All objects in a hash table are stored as type
Object. - As with objects stored in a Vector, you can cast
an object back to its original type when you
retrieve it. - Every object in a hash table must have a unique
key. (Don't confuse the key with the hash code
though. Even though all the keys are unique, the
hash codes may not be. This will result is
several object/key pairs jostling for the same
position in the table. This will be taken care of
under the covers by linking them together in a
list.) - You should check that the value returned from the
put() method is null. If it isn't, you are
displacing an object that was stored in the table
earlier using the same key
45Using your own Class Objects as Keys
- The equals() method is used by methods in the
Hashtable class to determine when two keys are
equal, so your version of this method should
return true when two different objects are equal
keys. This will generally amount to writing the
method so that it returns true when the data
members for the two objects that are used in the
hashCode() method are identical.
46Hashtable Example Code
- Hashtable theTable new Hashtable()
- Hashtable myTable new Hashtable(151)
- Hashtable aTable new Hashtable(151, 0.6f)
- // 60 load factor
- String myKey "Goofy"
- Integer theObject new Integer(12345)
- if (aTable.put (myKey, theObject) ! null
- System.out.println("Uh-oh, we bounced an object.
..")
47Hashtable Example Code cont.
- Note that the get() operation will return the
object corresponding to a key, but it does not
remove it from the table. To retrieve an object
and delete it from the table, you must use the
remove() method. This accepts a key of type
Object as an argument, and returns the object
corresponding to the key - theObject (Integer) aTable.remove(theKey)
- If there's no object stored corresponding to
theKey, null will be returned. If theKey is null,
the remove() method will throw NullPointerExceptio
n. Note how we have to explicitly cast the object
returned from the hash table to the correct
class.
48Processing all Elements in a Hash Table
- You can obtain an Enumeration for either of the
objects or the keys in a hash table. - The method elements() returns an Enumeration
referencing the objects stored, and the method
keys() returns an enumeration referencing the
keys for those objects. - You then have the choice of iterating through the
keys, which you can use with the get() method to
obtain the corresponding objects, so you have
both the keys and the objects available to you,
or using the elements() method and the
Enumeration returned, when you only want to
iterate through the objects.
49Processing Hashtable Elements
- Enumeration theKeys theTable.keys() // Get th
e keys - Name key
// Store a key - while(theKeys.hasMoreElements())
-
- key (Name)theKeys.nextElement() // Get ne
xt key - // Output the key and the person
- System.out.println("Key " key "\nPerson "
-
theTable.get(key)) -
50Other Hashtable Operations
- Remove all the objects references from a
Hashtable object - theTable.clear() // Empty the hash tab
le - The Hashtable class has methods capacity() and
size() to return the current capacity of the
table, and the number of objects stored in it. - You also have the isEmpty() method available
which returns true if no objects are stored in a
Hashtable object.
51Other Hashtable Operations
- There are two methods which enable you to check
whether an object is in a hash table. - The method contains() returns true if the object
passed as an argument is referenced at least once
in the table. - The method containsKey() returns true if the key
object passed as an argument has been stored
along with its associated object. - Both are determined using the equals() method for
the object passed as an argument, so if you want
this to work properly when you reference objects
of your own class, you'll need to have
implemented the equals() method for your class.
52Hashtable Program Examples
- See example programs from previous version of
text - Name.java
- Person.java
- TryHashTable.java
53Thats All Folks!