| ## Java 1.1 Unleashed # - 11 - The Utilities Package by Michael Girdley and Richard Lesh revised by Billy Barron IN THIS CHAPTER Linked Lists, Queues, Search Trees, and Other Dynamic Data Structures Using the Utilities Package Classes This chapter describes the classes in the `java.util` package in the Java class library. These classes implement many of those features or functions usually left for the programmer or someone else to implement. In programming experiences, I regularly find myself saying, "It would be so much easier if there were a built-in object that would do some common but complicated task." The `java.util` package is a well-designed and effective attempt to satisfy many of these specialized needs. In many languages, you find yourself implementing a stack or a hash table class and all the corresponding methods. Java has a built-in stack type that enables you to quickly and efficiently include your own stack data structures in your Java programs. This frees you to deal with more important design and implementation issues. These classes are also useful in a variety of other ways and are the fundamental building blocks of the more complicated data structures used in other Java packages and in your own applications. This chapter covers the following topics: Each of the features of the utilities package The implementation of most of the different classes in the utilities package NOTE: Unless otherwise noted, all the interfaces and classes discussed in this chapter extend the `java.lang.Object` class. Table 11.1 shows the classes that are part of the utilities package and that are discussed in this chapter. #### Table 11.1. Important classes in the utilities package.
Class | Description
`BitSet` | Implements a collection of binary values
`Calenda`r | Used to implement a calendar
`Date` | Used for date and time data storage and use
`Dictionary` | Used to store a collection of key and value pairs
`GregorianCalendar` | Used to implement a Gregorian calendar
`Hashtable` | Used to store a hash table
`Locale` | Used to implement a location
`Observable` | Used to store observable data
`Properties` | Used for storage of a properties list that can be saved
`Random` | Used to generate a pseudo-random number
`SimpleTimeZone` | Used to implement a simplified time zone
`Stack` | Used to store and implement a stack
`StringTokenizer` | Used to tokenize a string
`TimeZone` | Used to store information about a time zone
`Vector` | Used to store a vector data type
NOTE: You may not be familiar with some of these data types. The `Dictionary` class is used to implement a dictionary in your program. A `Hashtable` is a storage data type whose speed in searching is much greater than that of other data structures because it stores data items based on a key derived from some given formula. A `Stack`, of course, functions as if you were stacking data items on the floor, one on top of the other, in a single stack. As a consequence, the only two manipulations you can make to the stack are to remove the top item or to place another item on top. The `Vector` class implements an interesting data structure that has the capability to begin with a limited capacity and then change in size to accommodate the data items you insert into it. The `Vector` class can be described as a "growable array." ## Linked Lists, Queues, Search Trees, and Other Dynamic Data Structures One would expect that the `Vector` class would eliminate the necessity for creating your own data structures. But there may be times when you may want to conserve space to the maximum or access your data in a specialized way. In these cases, there is a technique to implement such data structures in Java. As you know, Java has no pointers. Because dynamically linked lists and queues are implemented using pointers, is it then impossible to create these two data structures in Java? Not quite. Just as with many other tasks in Java, you need to do a little "funky stepping" to get it right because the implementation of lists, queues, and other dynamic data structures is not intuitive. To define your own dynamic data structures, you will want to make use of the fact that references to objects in Java are already dynamic. This is demonstrated and necessitated by the practices Java uses, such as interfaces and abstract implementations. If you are accustomed to implementing dynamically linked lists or queues in C++, the format you use in Java to create your own version of these structures should seem very familiar to you. For example, the following code creates a `Node` class for the list that contains a string:
    class Node {
        String Name;
        Node Prev;
        Node Next;
    }
Of course, this code creates a doubly linked list, which has links backward and forward to other nodes containing strings. You could just as easily convert this type to link objects in just about any way to exhibit just about any behavior you want: queues, stacks (remember, there is already a `Stack` object in the class library), doubly linked lists, circular lists, binary search trees, and the list goes on. To implement such a list, you create a `DoubleList` class that contains one such `Node` object and links strung out from there. You can use the keyword `null` to represent an empty object. Here is an example of the `DoubleList` declaration:
    class DoubleList {
        // Declare the listhead to be of the Node type we created earlier.
        // Also, set it to be an empty object.
        Node ListHead = null;
    .
    .
    }
You then create methods to act on the list, such as `InsertNode()` or `ClearMyListJerk()`--whatever you want. You may also want to create a constructor method for the `Node` class that accepts parameters to set the previous and next nodes at construction time; or you may want to create a method such as `SetNext()` or `SetNextToNull()`. Either choice would work just fine. NOTE: Out of all this you get a surprise bonus: No worry about freeing space allocated to create nodes because the Java garbage collection processes take care of all that for you. Just create objects when you need them and let Java take care of it. ## Using the Utilities Package The utilities package has three interfaces, but you typically use only two: `Enumeration` and `Observer`. The other interface is `EventListener`; it is most commonly used internally by the AWT for handling events. Programmers only rarely implement the `EventListener` interface. An interface is a set of methods that must be written for any class that claims to implement the interface. This arrangement provides a way to consistently use all classes that implement the interface. Following is a summary of the `Enumeration` and `Observer` interfaces: E`numeration`. Interface for classes that can enumerate a vector `Observer`. Interface for classes that can observe observable objects The `Enumeration` interface is used for classes that can retrieve data from a list, element by element. For example, there is an `Enumeration` class in the utilities package that implements the `Enumeration` interface for use with the `Vector` class. This frees you from hard-core traversal of the different classes of data structures. The `Observer` interface is useful in designing classes that can watch for changes that occur in other classes. CAUTION: Some of the examples in this chapter are not applets--they are applications. Many of these data structures are best exhibited by just plain text input and output. Removing the baggage that would have come along with applets allows the examples to be simplified so that the topic being demonstrated is clearer. When you apply any code segments from this chapter in your own applets, remember that some of the examples are not true applets; you must deal with the differences inherent between applets and applications. ### The Enumeration Interface The `Enumeration` interface specifies a set of methods used to enumerate--that is, iterate through--a list. An object that implements this interface can be used to iterate through a list only once because the `Enumeration` object is consumed through its use. For example, an `Enumeration` object can be used to print all the elements of a `Vector` object, `v`, as follows:
    for (Enumeration e=v.elements();e.hasMoreElements();)
        System.out.print(e.nextElement()+" ");
The `Enumeration` interface specifies only two methods: `hasMoreElements()` and `nextElement()`. The `hasMoreElements()` method must return `true` if there are elements remaining in the enumeration. The `nextElement()` method must return an object representing the next element within the object being enumerated. The details of how the `Enumeration` interface is implemented and how the data is represented internally are left up to the implementation of the specific class. ### The Observer Interface The `Observer` interface, if implemented by a class, allows an object of the class to observe other objects of the class `Observable`. The `Observer` interface is notified whenever the `Observable` object that it is watching changes. The interface only specifies one method, `update(Observable, Object)`. This method is called by the observed object to notify the `Observer` of changes. A reference to the observed object is passed along with any additional object that the observed object wants to pass to the `Observer`. The first argument enables the `Observer` to operate on the observed object; the second argument is used to pass information from the observed to the `Observer`. ## Classes The utilities package supplies many different classes that provide a wide variety of functionality. Although these classes don't generally have much in common, they all provide support for the most common data structures used by programmers. The techniques described in the next sections enable you to create your own specialized classes to supplement those missing from the package. The classes supplied in the `java.util` package, however limited they are, do provide a great advantage over other languages. The main advantage is that these classes simplify some things and eliminate a lot of the garbage you were stuck with in the past, in terms of freeing memory and doing mundane programming tasks. However, there are a number of limitations. For example, you have to "dance a little bit" to implement some of the more complicated data structures. And if you want speed, there are much faster languages to choose from. Java provides a combination of power and simplicity while sacrificing speed. However, don't worry that your programs will be slugs. Although Java is not nearly as efficient as C++ and C, it still beats Visual Basic in terms of size and speed. ### The BitSet Class The `BitSet` class implements a data type that represents a collection of bits. The collection grows dynamically as more bits are required. The class is useful for representing a set of `true` and `false` values. Specific bits are identified using nonnegative integers. The first bit is bit `0`. The `BitSet` class is most useful for storing a group of related `true/false` values, such as user responses to Yes and No questions. For example, if the applet has a number of radio buttons, you can slap those values into an instance of the `BitSet` class. The class is also useful in terms of bitmapping your own graphics. You can create bitsets that represent a pixel at a time (of course, it would be much easier to use the `Graphics` class for this purpose instead). Individual bits in the set are turned on or off with the `set()` and `clear()` methods. Individual bits are queried with the `get()` method. These methods all take the specific bit number as their only argument. The basic boolean operations `AND`, `OR`, and `XOR` can be performed on two bitsets using the `and()`, `or()`, and `xor()` methods. Because these methods modify one of the bitsets, you generally use the `clone()` method to create a duplicate of one bitset, and then use the `AND`, `OR`, or `XOR` operation on the clone with the second bitset. The result of the operation then ends up in the cloned bitset. The `BitSet1` program in Listing 11.1 shows the basic `BitSet` operations. #### Listing 11.1. BitSet1.java: a sample BitSet program.
    import java.io.DataInputStream;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.BitSet;
    class BitSet1 {
        public static void main(String args[])
            throws java.io.IOException
        {
            BufferedReader dis=new BufferedReader(new InputStreamReader(System.in));
            String bitstring;
            BitSet set1,set2,set3;
            set1=new BitSet();
            set2=new BitSet();
            // Get the first bit sequence and store it
            System.out.println("Bit sequence #1:");
            bitstring=dis.readLine();
            for (short i=0;i<bitstring.length();i++){
                if (bitstring.charAt(i)=='1')
                    set1.set(i);
                else
                    set1.clear(i);
            }
            // Get the second bit sequence and store it
            System.out.println("Bit sequence #2:");
            bitstring=dis.readLine();
            for (short i=0;i<bitstring.length();i++){
                if (bitstring.charAt(i)=='1')
                    set2.set(i);
                else
                    set2.clear(i);
            }
            System.out.println("BitSet #1: "+set1);
            System.out.println("BitSet #2: "+set2);
            // Test the AND operation
            set3=(BitSet)set1.clone();
            set3.and(set2);
            System.out.println("set1 AND set2: "+set3);
            // Test the OR operation
            set3=(BitSet)set1.clone();
            set3.or(set2);
            System.out.println("set1 OR set2: "+set3);
            // Test the XOR operation
            set3=(BitSet)set1.clone();
            set3.xor(set2);
            System.out.println("set1 XOR set2: "+set3);
        }
    }
The output from this program looks like this:
    Bit sequence #1:
    1010
    Bit sequence #2:
    1100
    BitSet #1: {0, 2}
    BitSet #2: {0, 1}
    set1 AND set2: {0}
    set1 OR set2: {0, 1, 2}
    set1 XOR set2: {1, 2}
Table 11.2 summarizes all the methods available in the `BitSet` class. #### Table 11.2. Methods in the BitSet interface.
Method | Description
| Constructors
`BitSet()` | Constructs an empty `BitSet`
`BitSet(int)` | Constructs an empty `BitSet` of a given size
| Methods
`and(BitSet)` | Logically `AND`s the object's bitset with another `BitSet` object
`clear(int)` | Clears a specific bit
`clone()` | Creates a clone of the `BitSet` object
`equals(Object)` | Compares this object against another `BitSet` object
`get(int)` | Returns the value of a specific bit
`hashCode()` | Returns the hash code
`or(BitSet)` | Logically `OR`s the object's bitset with another `BitSet` object
`set(int)` | Sets a specific bit
`size()` | Returns the size of the set
`toString()` | Converts bit values to a string representation
`xor(BitSet)` | Logically `XOR`s the object's bitset with another `BitSet` object
In addition to extending the `java.lang.Object` class, `BitSet` implements the `java.lang.Cloneable` interface. This, of course, allows instances of the object to be cloned to create another instance of the class. ### The Calendar Class The `Calendar` class is an abstract class used to convert dates. You can use this class to convert a `Date` object to fields, such as `YEAR`, `MONTH`, `HOUR`, and so on. You can also use these fields to update a `Date` object. In the API definition, only one subclass of `Calendar` exists: `GregorianCalendar`. Because most people and virtually all businesses in the world use the Gregorian calendar, you will find all the details about calendars in that section, later in this chapter. Table 11.3 summarizes the methods available in the `Calendar` class. #### Table 11.3. Methods in the Calendar class.
Method | Description
| Constructors
`Calendar()` | Creates a calendar with the default `TimeZone` and `Locale`
`Calendar(TimeZone,Locale)` | Creates a calendar with the given `TimeZone` and `Locale`
| Static Methods
`getDefault()` | Returns a calendar with the default `TimeZone` and `Locale`
`getDefault(TimeZone)` | Returns a calendar with the default `Locale` and given `TimeZone`
`getDefault(Locale)` | Returns a calendar with the given `Locale` and default `TimeZone`
`getDefault(TimeZone,Locale)` | Returns a calendar with the given `TimeZone` and `Locale`
`getAvailableLocales()` | Returns an array of all available locales
| Methods
`getTime()` | Returns the date and time
`setTime(Date)` | Sets the date and time
`get(byte)` | Returns the specified field
`set(byte,int)` | Sets the specified field to the specified value
`set(int,int,int)` | Sets the year, month, and date
`set(int,int,int,int,int)` | Sets the year, month, date, hour, and minute
`set(int,int,int,int,int,int)` | Sets the year, month, date, hour, minute, and second
`clear()` | Clears all fields
`clear(byte)` | Clears the specified field
`isSet(int)` | Returns `true` if the specified field is set
`equals(Object)` | Returns `true` if two objects are the same
`before(Object)` | Returns `true` if this object is before the given object
`after(Object)` | Returns `true` if this object is after the given object
`add(byte,int)` | Adds the given value to the field
`roll(byte,boolean)` | Increments or decrements (depending on the `boolean` value) the specified field by one unit
`setTimeZone(TimeZone)` | Sets the time zone this object is in
`setValidationMode(boolean)` | If the `boolean` value is set to `true`, invalid dates are allowed
`getValidationMode()` | Returns whether or not invalid dates are allowed
`setFirstDayOfWeek(byte)` | Sets the first day of the week
`getFirstDayOfWeek()` | Returns the first day of the week
`setMinimumDaysInFirstWeek(byte)` | Sets how many days are required to define the first week of the month
`getMinimumDaysInFirstWeek()` | Returns how many days are required to define the first week of the month
`getMinimum(byte)` | Returns the minimum possible value for the given field
`getMaximum(byte)` | Returns the maximum possible value for the given field
`getGreatestMinimum(byte)` | Returns the greatest possible minimum value for the field
`getLeastMaximum(byte)` | Returns the least possible maximum value for the given field
`Clone()` | Makes a copy of this object
NOTE: The use of the terms greatest minimum and least maximum may have confused you in Table 11.3. An example of least maximum is the question "what is the least maximum day in any month?" The answer is 28--from February, where the maximum day is 28 (in most years). For the Gregorian calendar (which most of us use), `getGreatestMinimum()` always returns the same value as `getMinimum()`. ### The Date Class Before Java 1.1, the `Date` class was an extremely important class for handling dates and times. However, it was weak in some areas such as internationalization and dealing with the differences in daylight saving time in different locations. With Java 1.1, the `Date` class has been relegated to just storing the exact time. Most of the old `Date` class methods have been deprecated and should no longer be used. All the methods for converting time between binary and human-readable form are now handled by the `Calendar`, `GregorianCalendar`, `TimeZone`, `SimpleTimeZone`, and `Locale` classes. An example of how these classes can work together is found in Listing 11.3, in "The `GregorianCalendar` Class," later in this chapter. The default constructor is used when the current date and time are required. The other constructor takes a millisecond representation of time and creates a `Date` object based on it. When a date is converted to a string by an automatic coercion, the `toString()` method is used. The resulting string returned by the `toString()` function follows UNIX time and date standards. Dates can be compared to each other by using their UTC values (the UTC value is the number of seconds since January 1, 1970) or by using the methods `after()`, `before()`, and `equals()`. CAUTION: Don't try to launch space shuttles or coordinate nuclear attacks based on your operating system's local time as reflected by Java. Although the API is intended to reflect UTC (Coordinated Universal Time), it doesn't do so exactly. This inexact behavior is inherited from the time system of the underlying OS. The vast majority of all modern operating systems assume that one day equals 3600 seconds/hour multiplied by 24 hours, and as such, they reflect time to the accuracy that UTC does. Under the UTC, about once a year, there is an extra second, called a "leap second," added to account for the wobble of the earth. Most computer clocks are not accurate enough to reflect this distinction. Between UTC and standard OS time (UT/GMT), there is this subtle difference; one is based on an atomic clock and the other is based on astronomical observations, which, for all practical purposes, is an invisibly fine hair to split. For more information, Sun suggests you visit the U.S. Naval Observatory site, particularly the Directorate of Time at `http://tycho.usno.navy.mil` and its definitions of different systems of time at `http://tycho.usno.navy.mil/systime.html`. Table 11.4 summarizes all the nondeprecated methods available in the `Date` class. You can find the deprecated methods by looking at the API reference included with the JDK or found on JavaSoft's Web site (`http://www.javasoft.com/`). #### Table 11.4. Useable methods available in the Date interface.
Method | Description
| Constructors
`Date()` | Constructs a date using today's date and time
`Date(long)` | Constructs a date using a single UTC value
| Methods
`after(Date)` | Returns `true` if the date is later than the specified date
`before(Date)` | Returns `true` if the date is earlier than the specified date
`equals(Object)` | Returns `true` if the date and the specified date are equal
`getTime()` | Returns the time as a single UTC value
`hashCode()` | Computes a hash code for the date
`setTime(long)` | Sets the time using a single UTC value
`toString()` | Converts a date to text using UNIX `ctime()` conventions
You will also find the `before()` and `after()` functions useful. They enable you to send in another instance of the `Date` class and compare that date to the value in the calling instance. The sample applet in Listing 11.2 demonstrates the use of the `Date` class. #### Listing 11.2. Using the Date class.
    import java.awt.*;
    import java.util.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    public class MichaelSimpleClock extends java.applet.Applet {
        Button DateButton = new Button(
            "                   Click me!                     ");
        public void init()  {
            ButtonListener bl = new ButtonListener(DateButton);
            add(DateButton);
         DateButton.addActionListener(bl);
        }
    }

    class ButtonListener implements ActionListener {
        Date TheDate = new Date();
        Button theButton;

        public ButtonListener(Button aButton) {
         theButton = aButton;
        }

        public void actionPerformed (ActionEvent e) {
                theButton.setLabel(TheDate.toString());
        }
    }
Figure 11.1 shows the `MichaelSimpleClock` applet. Note that the clock in the applet is wrong: it is not actually 8:00 A.M. There is no way I would write that early in the morning! Figure 11.1. The MichaelSimpleClock applet. What about a real-time clock that updates as the clock changes? To accomplish this small feat, you must include in the applet a loop that has each iteration reconstructing the internal `Date` instance. Then you regularly repaint that value inside the applet's `paint()` method. You also have to include threading to keep your system from locking up during the applet's execution. Threading is covered in Chapter 6, "Threads and Multithreading," so a real-time clock was not included in this chapter. ### The GregorianCalendar Class Before 1582, the western world used the Julian calendar system, which was adopted by Julius Caesar. The problem with the Julian calendar was that it had too many leap years (3 too many every 400 years). Pope Gregory XIII fixed that problem. In addition, the Julian year started on March 25; the Gregorian calendar year starts on January 1. At the time of the switch, the last day of the Julian calendar was October 4, 1582, and the first day of the Gregorian calendar was October 15, 1582. The dates in between never occurred. However, this was not true for England and America, which kept the Julian calendar until 1752. When England and America switched, the last Julian day was September 2, 1752, and the first Gregorian date was September 14, 1752. If you are working on historical dates, I strongly recommend that you do some additional reading on this subject! The `GregorianCalendar` class handles conversions between actual dates and data fields such as month for the Gregorian calendar. The Gregorian calendar is the most widely used calendar system in the world. However, in fact, this class also handles the Julian calendar system. Table 11.5 summarizes the methods available in the `GregorianCalendar` class. #### Table 11.5. Methods in the GregorianCalendar class.
Method | Description
| Constructors
`GregorianCalendar()` | Creates a Gregorian calendar using the current time with the default `TimeZone` and `Locale`
`GregorianCalendar(TimeZone)` | Creates a Gregorian calendar using the current time with the default `Locale` and the given `TimeZone`
`GregorianCalendar(TimeZone,Locale)` | Creates a Gregorian calendar with the current time and the given `TimeZone` and `Locale`
`GregorianCalendar(int,int,int)` | Creates a Gregorian calendar at the given year, month, and date with the default `TimeZone` and `Locale`
`GregorianCalendar(int,int,int,int,int)` | Creates a Gregorian calendar at the given year, month, date, hour, and minute with the default `TimeZone` and `Locale`
`GregorianCalendar(int,int,int,int,int,int)` | Creates a Gregorian calendar at the given year, month, date, hour, minute, and second with the default `TimeZone` and `Locale`
`GregorianCalendar(Locale)` | Creates a Gregorian calendar at the current time with the default `TimeZone` and the given `Locale`
| Methods
`setGregorianChange(Date)` | Sets the date that the Julian calendar changed to the Gregorian calendar
`getGregorianChange()` | Returns the date that the Julian calendar changed to the Gregorian calendar
`isLeapYear()` | Returns `true` if the year of this object is a leap year
`equals(Objects)` | Returns `true` if the two objects are equal
`before(Object)` | Returns `true` if this object is before the date of the object given
`after(Object)` | Returns `true` if the object is after the date of the object given
`add(byte,amount)` | Adds the `amount` given to the field specified by `byte`
`roll(byte,boolean)` | Increments or decrements (depending on the `boolean` value) the specified field by one unit
`getMinimum(byte)` | Returns the minimum value for the specified field
`getMaximum(byte)` | Returns the maximum value for the specified field
`getGreatestMinimum(byte)` | Returns the greatest minimum value for the specified field
`getLeastMaximum(byte)` | Returns the least maximum value for the specified field
`clone()` | Makes a copy of this object
Listing 11.3 shows the use of the `GregorianCalendar` class as well as many other classes in the utilities package. #### Listing 11.3. A program to calculate the day of week.
    import java.util.*;
    public class cal {
       public static void main(String args[]) {
           int msecsInHour = 60*60*1000;
           SimpleTimeZone cst = new SimpleTimeZone(-6*msecsInHour,"CST");
           cst.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2*msecsInHour);
           cst.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*msecsInHour);
           Calendar calendar = new GregorianCalendar(cst);

           System.out.println("Day of Week: " + calendar.get(Calendar.DAY_OF_WEEK));
       }
    }
### The Locale Class The `Locale` class is used to define a locale. A locale is a combination of a geographic location, a language, and a variant. The variant is usually a browser-specific code. The `Locale` class is key in using internationalization in your Java code. The `Locale` class enables you to write your program independent of country and language. Specific behaviors for each country and language can easily be added later when they are needed. The ISO (International Standards Organization) language codes are documented in standard ISO-639 (`http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt`). The ISO country codes are documented in standard ISO-3166 (`http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html`). An example of a country code is `"US"` (for the United States). An example of a language code is `"EN"` (for English). Some example of variants are `WIN` (for Windows), `MAC` (for Macintosh), and `POSIX` (for UNIX). Table 11.6 lists the methods available in the `Locale` class. #### Table 11.6. Methods available with the Locale class.
Method | Description
| Constructor
`Locale(String, String`) | Creates a locale based on a given language and country
`Locale(String, String, String`) | Creates a locale based on a given language, country, and variant
| Static Methods
`getDefault()` | Returns the default `Locale`
`setDefault(Locale)` | Sets the default `Locale`
| Methods
`getLanguage()` | Returns the language in use
`getCountry()` | Returns the country in use
`getISO3Language()` | Returns the three-character ISO code for the language
`getISO3Country()` | Returns the three-character ISO code for the country
`getVariant()` | Returns the variant in use
`toString()` | Returns the object as a `String`
`getDisplayLanguage()` | Returns the language to display to the user
`getDisplayLanguage(Locale)` | Returns the language to display to the user based on the given `Locale`
`getDisplayCountry()` | Returns the country to display to the user
`getDisplayCountry(Locale)` | Returns the country to display to the user for the given `Locale`
`getDisplayVariant()` | Returns the variant to display to the user
`getDisplayVariant(Locale)` | Returns the variant to display to the user for the given `Locale`
`getDisplayName()` | Returns the language, country, and variant to display to the user
`getDisplayName(Locale)` | Returns the language, country, and variant to display to the user for the given `Locale`
`clone()` | Makes a copy of this locale
`hashCode()` | Returns the hash code for this locale
`equals(Object)` | Returns `true` if two locales are equal
> ### The Random Class For the programming of games and many other program types, it is important to be able to generate random numbers. Java includes the capability to generate random numbers efficiently and effectively. The `Random` class implements a pseudo-random number data type that generates a stream of seemingly random numbers. To create a sequence of different pseudo-random values each time the application is run, create the `Random` object as follows: `Random r=new Random();` This statement seeds the random generator with the current time. On the other hand, consider the following statement: `Random r=new Random(326); // Pick any value` This statement seeds the random generator with the same value each time, resulting in the same sequence of pseudo-random numbers each time the application runs. The generator can be reseeded at any time using the `setSeed()` method. TIP: Want to get really random numbers? Well, you can't. But a common practice to simulate actual random numbers in computer programs is to seed the random number generator with some variant of the current time or date. If, for example, you want to seed a random number generator with the sum of the current seconds, minutes, and hours, you could use this code, which should suffice for most tasks:
>     int OurSeed = ADate.getSeconds() + ADate.getHours() + ADate.getMinutes();
>     Random = new Random(OurSeed);
Pseudo-random numbers can be generated using one of these functions: `nextInt()`, `nextLong()`, `nextFloat()`, `nextDouble()`, or `nextGaussian()`. The first four functions return integers, longs, floats, and doubles. For more information about the Gaussian distribution, refer to the following sidebar. The `Random1` program in Listing 11.4 prints five pseudo-random uniformly distributed values using these functions. #### Listing 11.4. Random1.java: A sample Random program.
    import java.lang.Math;
    import java.util.Date;
    import java.util.Random;
    class Random1 {
        public static void main(String args[])
            throws java.io.IOException
        {
            int count=6;
            Random randGen=new Random();
            System.out.println("Uniform Random Integers");
            for (int i=0;i<count;i++)
            System.out.print(randGen.nextInt()+" ");
            System.out.println("\n");
            System.out.println("Uniform Random Floats");
            for (int i=0;i<count;i++)
            System.out.print(randGen.nextFloat()+" ");
            System.out.println("\n");
            System.out.println("Gaussian Random Floats");
            for (int i=0;i<count;i++)
                System.out.print(randGen.nextGaussian()+" ");
            System.out.println("\n");
            System.out.println("Uniform Random Integers [1,6]");
            for (int i=0;i<count;i++)
                System.out.print((Math.abs(randGen.nextInt())%6+1)+" ");
            System.out.println("\n");
            }
    }
The output from the preceding program looks like this:
    Uniform Random Integers
    1704667569 -1431446235 1024613888 438489989 710330974 -1689521238
    Uniform Random Floats
    0.689189 0.0579988 0.0933537 0.748228 0.400992 0.222109
    Gaussian Random Floats
    -0.201843 -0.0111578 1.63927 0.205938 -0.365471 0.626304
    Uniform Random Integers [1,6]
    4 6 1 6 3 2
If you want to generate uniformly distributed random integers within a specific range, the output from `nextInt()`, `nextLong()`, or `nextDouble()` can be scaled to match the required range. However, a simpler approach is to take the remainder of the result of `nextInt()` divided by the number of different values plus the first value of the range. For example, if the values 10 to 20 are needed, you can use the formula `nextInt()%21+10`. Unfortunately, although this method is much simpler than scaling the output of `nextInt(),` it is guaranteed to work only on truly random values. Because the pseudo-random generator may have various undesired correlations, the `modulus` operator may not provide acceptable results--you might get all odd numbers, for example. In other words, don't plan on simulating the detonation of your new H-bomb in Java because you may find yourself a couple miles too close. GAUSSIAN AND NORMAL DISTRIBUTIONS Uniformly distributed random numbers are generated using a modified linear congruential method with a 48-bit seed. Uniformly distributed random numbers within a given range all appear with the same frequency. The `Random` class can also generate random numbers in a Gaussian or normal distribution. The Gaussian frequency distribution curve is also referred to as a bell curve. For information on the Gaussian frequency distribution curve, see The Art of Computer Programming, Volume 2, by Donald Knuth. Table 11.7 summarizes the complete interface of the `Random` class. #### Table 11.7. The methods available in the Random interface.
Method | Description
| Constructors
`Random()` | Creates a new random number generator
`Random(long)` | Creates a new random number generator using a seed
| Methods
`nextDouble()` | Returns a pseudo-random, uniformly distributed double
`nextFloat()` | Returns a pseudo-random, uniformly distributed float
`nextGaussian()` | Returns a pseudo-random, Gaussian distributed double
`nextInt()` | Returns a pseudo-random, uniformly distributed integer
`nextLong()` | Returns a pseudo-random, uniformly distributed long
`setSeed(long)` | Sets the seed of the pseudo-random number generator
The applet shown in Listing 11.5 demonstrates a bit of what you can do with the `Random` class. #### Listing 11.5. Using the Random class.
    import java.awt.*;
    import java.util.*;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;

    public class TheWanderer extends java.applet.Applet {
            int xpos = 100;
            int ypos = 100;
        // Our current date.
        Calendar C = new GregorianCalendar();
            // The movement button
            Button theButton = new Button("Click Me");
            // Our random number generator.
            Random R;
            public void init() {
                    SimpleListener simple = new SimpleListener(this);
                    add(theButton);
                    theButton.addActionListener(simple);
                    setBackground(Color.white);
            // Our random number generator seeded with the current seconds.
            int seed = C.get(Calendar.SECOND);
                    R = new Random(seed);
            }
        public void paint(Graphics g) {
                    g.setColor(Color.black);
                    g.fillOval(xpos,ypos, 50, 50);
        }

        public void move() {
                            // Move our thing.
                            xpos = xpos + (Math.abs(R.nextInt())%10-7);
                            ypos = ypos + (Math.abs(R.nextInt())%10-7);
                // repaint the sucker.
                            repaint();
        }
    }

    class SimpleListener implements ActionListener {
            private TheWanderer theClass;

            public SimpleListener(TheWanderer aClass) {
                    theClass = aClass;
                }
            public void actionPerformed (ActionEvent e) {
                    theClass.move();
                }
        }
Figure 11.2 shows `TheWanderer` applet during its execution. Figure 11.2. `TheWanderer` applet. ### The SimpleTimeZone Class The `SimpleTimeZone` class is a simple `TimeZone` that can be used with the `GregorianCalendar` class. The `SimpleTimeZone` class assumes that time-zone rules have not changed historically. Additionally, it assumes that the rules are of a simple nature. Even with these limitations, this class can handle the needs of the majority of programmers. Listing 11.3, earlier in this chapter, provides an example of how to use this class. Table 11.8 summarizes the methods available with the `SimpleTimeZone` class. #### Table 11.8. Methods available with the SimpleTimeZone class.
Method | Description
| Constructor
`SimpleTimeZone(int,String)` | Creates a `TimeZone` with the given offset and time-zone name
`SimpleTimeZone(int,String,int,int,` | Creates a `TimeZone` with the given offset,
`int,int,int,int,int,int)` | time-zone name, and time to start and end daylight saving time
| Methods
`setStartYear(int)` | Sets the first year that daylight saving time started
`setStartRule(int,int,int,int)` | Sets the rule for the beginning of daylight saving time based on the month, week, day of week, and time of day
`setEndRule(int,int,int,int)` | Sets the rule for the end of daylight saving time based on the month, week, day of week, and time of day
`getOffset(int,int,int,int,int,int)` | Returns the Greenwich mean time (GMT) offset for a given time
`getRawOffset()` | Returns the GMT offset for the current time
`setRawOffset(int)` | Sets the base GMT offset
`useDaylightTime()` | Returns `true` if this `TimeZone` uses daylight saving time
`inDaylightTime(Date)` | Returns `true` if the given date is in daylight saving time
`clone()` | Makes a copy of this object
`hashCode()` | Returns the hash code for this object
`equals(Object)` | Returns `true` if this object is equal to the one given
### The StringTokenizer Class This section describes the function of the `StringTokenizer` class, which also could have been appropriately grouped with the other classes in Chapter 12, "The I/O Package," because it is so vital to the input and output functions demonstrated in that chapter. The `StringTokenizer` class enables you to parse a string into a number of smaller strings called tokens. This class works specifically for what is called "delimited text," which means that each individual substring of the string is separated by a delimiter. The delimiter can be anything ranging from an `*` to `YabaDaba`. You simply specify what you want the class to look for when tokenizing the string. This class is included in this chapter because it has uses that prove helpful in everything from a spreadsheet applet to an arcade game applet. The delimiter set can be specified when the `StringTokenizer` object is created, or it can be specified on a per-token basis. The default delimiter set is the set of whitespace characters. With this delimiter set, the class would find all the separate words in a string and tokenize them. For example, the `StringTokenizer1` code in Listing 11.6 prints out each word of the string on a separate line. #### Listing 11.6. StringTokenizer1.java: A sample StringTokenizer program.
    import java.io.DataInputStream;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
    class StringTokenizer1 {
        public static void main(String args[])
            throws java.io.IOException
        {
            BufferedReader dis=new BufferedReader(new InputStreamReader(System.in));
            System.out.println("Enter a sentence: ");
            String s=dis.readLine();
            StringTokenizer st=new StringTokenizer(s);
            while (st.hasMoreTokens())
                System.out.println(st.nextToken());
        }
    }
Here is the output from this listing:
    Enter a sentence:
    Four score and seven
    Four
    score
    and
    seven
Pure excitement. The method `countTokens()` returns the number of tokens remaining in the string using the current delimiter set--that is, the number of times `nextToken()` can be called before generating an exception. This is an efficient method because it does not actually construct the substrings that `nextToken()` must generate. In addition to extending the `java.lang.Object` class, the `StringTokenizer` class implements the `java.util.Enumeration` interface. Table 11.9 summarizes the methods of the `StringTokenizer` class. #### Table 11.9. The methods available in the StringTokenizer interface.
Method | Description
| Constructors
`StringTokenizer` | Constructs a `StringTokenizer` given a
`(String)` | string using whitespace as delimiters
`StringTokenizer` | Constructs a `StringTokenizer` given a
`(String, String)` | string and a delimiter set
`StringTokenizer` | Constructs a `StringTokenizer` given a
`(String, String, boolean)` | string and a delimiter set; the final parameter is a boolean value which, if `true`, says that the delimiters must be returned as tokens (if this parameter is `false`, the tokens are not returned)
| Methods
`countTokens()` | Returns the number of tokens remaining in the string
`hasMoreTokens()` | Returns `true` if more tokens exist
`nextToken()` | Returns the next token of the string
`nextToken(String)` | Returns the next token, given a new delimiter set
`hasMoreElements()` | Returns `true` if more elements exist in the enumeration
`nextElement()` | Returns the next element of the enumeration using the current delimiter set
### The TimeZone Class The `TimeZone` class is a generic class that represents any kind of time zone. This class contains the offset from Greenwich mean time (GMT) and can deal with daylight saving time. Table 11.10 lists the methods available with the `TimeZone` class. #### Table 11.10. Methods available with the TimeZone class.
Method | Description
| Constructor
`TimeZone()` | Creates a `TimeZone`
| Static Methods
`getTimeZone(String)` | Returns the `TimeZone` object given the name of the time zone
`getAvailableIDs()` | Returns an array of all `TimeZone` names
`getAvailableIDs(int)` | Returns an array of all `TimeZone` names that apply to a particular offset
`getDefault()` | Returns the default `TimeZone` for this machine
`setDefault(TimeZone)` | Sets the default `TimeZone` for this machine
| Methods
`getOffset(int,int,int,int,int,int)` | Returns the GMT offset for the local `TimeZone` at the time given
`getRawOffset()` | Returns the GMT offset for the local `TimeZone` at the current time
`getID()` | Returns the name of the `TimeZone`
`setID(String)` | Sets the name of the `TimeZone`
`useDaylightTime()` | Returns `true` if this `TimeZone` uses daylight saving time
`inDaylightTime(Date)` | Returns `true` if the date given is in daylight saving time for this `TimeZone`
`clone()` | Makes a copy of this object
### The Vector Class As stated earlier in this chapter, Java doesn't include dynamically linked lists, queues, or other data structures of that type. Instead, the designers of Java envisioned the `Vector` class, which handles the occasions when you need to dynamically store objects. Of course, there are positive and negative consequences of this decision by the designers at Sun. On the positive side, the `Vector` class contributes to the simplicity of the language. The major negative point is that, at face value, the `Vector` class severely limits programmers from using more sophisticated programs. In any case, the `Vector` class implements a dynamically allocated list of objects. It attempts to optimize storage by increasing the storage capacity of the list when needed by increments larger than just one object. Typically, with this mechanism, there is some excess capacity in the list. When this capacity is exhausted, the list is reallocated to add another block of objects at the end of the list. Setting the capacity of the `Vector` object to the needed size before inserting a large number of objects reduces the need for incremental reallocation. Because of this mechanism, it is important to remember that the capacity (the available elements in the `Vector` object) and the size (the number of elements currently stored in the `Vector` object) usually are not the same. Suppose that a `Vector` with `capacityIncrement` equal to `3` has been created. As objects are added to the `Vector`, new space is allocated in chunks of three objects. After five elements have been added, there is still room for one more element without the need for any additional memory allocation. After the sixth element has been added, there is no more excess capacity. When the seventh element is added, a new allocation is made to add three additional elements, giving a total capacity of nine. After the seventh element is added, there are two remaining unused elements. The initial storage capacity and the capacity increment can both be specified in the constructor. Even though the capacity is automatically increased as needed, the `ensureCapacity()` method can be used to increase the capacity to a specific minimum number of elements; the `trimToSize()` method can be used to reduce the capacity to the minimum number of elements needed to store the current amount. New elements can be added to the `Vector` using the `addElement()` and `insertElementAt()` methods. The elements passed to be stored in the `Vector` must be derived from type `Object`. Elements can be changed using the `setElementAt()` method. Removal of elements is accomplished with the `removeElement()`, `removeElementAt()`, and `removeAllElements()` methods. Elements can be accessed directly using the `elementAt()`, `firstElement()`, and `lastElement()` methods; elements can be located using the `indexOf()` and `lastIndexOf()` methods. Information about the size and the capacity of the `Vector` are returned by the `size()` and `capacity()` methods. The `setSize()` method can be used to directly change the size of the `Vector`. For example, the `Vector1` code in Listing 11.7 creates a `Vector` of integers by adding new elements to the end. Then, using a variety of techniques, it prints the `Vector`. #### Listing 11.7. Vector1.java: A sample Vector program.
    import java.lang.Integer;
    import java.util.Enumeration;
    import java.util.Vector;
    class Vector1 {
        public static void main(String args[]){
            Vector v=new Vector(10,10);
            for (int i=0;i<20;i++)
                v.addElement(new Integer(i));
            System.out.println("Vector in original order using an Enumeration");
            for (Enumeration e=v.elements();e.hasMoreElements();)
                System.out.print(e.nextElement()+" ");
            System.out.println();
            System.out.println("Vector in original order using elementAt");
            for (int i=0;i<v.size();i++)
                System.out.print(v.elementAt(i)+" ");
            System.out.println();
            // Print out the original vector
            System.out.println("\nVector in reverse order using elementAt");
            for (int i=v.size()-1;i>=0;i++)
                System.out.print(v.elementAt(i)+" ");
            System.out.println();
            // Print out the original vector
            System.out.println("\nVector as a String");
            System.out.println(v.toString());
        }
    }
The output from this program looks like this:
    Vector in original order using an Enumeration
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
    Vector in original order using elementAt
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
    Vector in reverse order using elementAt
    19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    Vector as a String
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
NOTE: The expression new `Integer()` was used to create integer objects to store because the fundamental types, such as `int`, are not objects in Java. This technique is used many times throughout this chapter. Notice the use of the `Enumeration` object as one way to access the elements of a `Vector`. Look at the following lines:
    for (Enumeration e=v.elements();e.hasMoreElements();)
    System.out.print(e.nextElement()+" ");
You can see that an `Enumeration` object, which represents all the elements in the `Vector`, is created and returned by the `Vector` method `elements()`. With this `Enumeration` object, the loop can check to see whether there are more elements to process using the `Enumeration` method `hasMoreElements()`; the loop can get the next element in the `Vector` using the `Enumeration` method `nextElement()`. The `Vector2` program in Listing 11.8 shows some of the vector-accessing techniques. It first generates a vector of random integers; then it allows the user to search for a specific value. The locations of the first and last occurrences of the value are printed by the program using the `indexOf()` and `lastIndexOf()` methods. #### Listing 11.8. Vector2.java: Another sample Vector program.
    import java.io.DataInputStream;
    import java.io.InputStreamReader;
    import java.io.BufferedReader;
    import java.lang.Integer;
    import java.lang.Math;
    import java.util.Enumeration;
    import java.util.Random;
    import java.util.Vector;
    class Vector2 {
        public static void main(String args[])
            throws java.io.IOException
        {
            int numElements;
            BufferedReader dis=new BufferedReader(new InputStreamReader(System.in));
            Vector v=new Vector(10,10);
            Random randGen=new Random();
            System.out.println("How many random elements? ");
            numElements=Integer.valueOf(dis.readLine()).intValue();
            for (int i=0;i<numElements;i++)
                v.addElement(new Integer(Math.abs(
                    randGen.nextInt())%numElements));
            System.out.println(v.toString());
            Integer searchValue;
            System.out.println("Find which value? ");
            searchValue=Integer.valueOf(dis.readLine());
            System.out.println("First occurrence is element "+
                v.indexOf(searchValue));
            System.out.println("Last occurrence is element "+
                v.lastIndexOf(searchValue));
        }
    }
The output from this program looks like this:
    How many random elements?
    10
    [0, 2, 8, 4, 9, 7, 8, 6, 3, 2]
    Find which value?
    8
    First occurrence is element 2
    Last occurrence is element 6
In addition to extending the `java.lang.Object` class, the `Vector` class implements the `java.lang.Cloneable` interface. Table 11.11 summarizes the methods of the `Vector` class. #### Table 11.11. The variables and methods available in the Vector interface.
Variable | Description
`capacityIncrement` | Size of the incremental allocations, in elements
`elementCount` | Number of elements in `Vector`
`elementData` | Buffer in which the elements are stored
Method | Description
| Constructors
`Vector()` | Constructs an empty vector
`Vector(int)` | Constructs an empty vector with the specified storage capacity
`Vector(int, int)` | Constructs an empty vector with the specified storage capacity and capacity increment
| Methods
`addElement(Object)` | Adds the specified object at the end of the `Vector`
`capacity()` | Returns the capacity of the `Vector`
`clone()` | Creates a clone of the `Vector`
`contains(Object)` | Returns `true` if the specified object is in the `Vector`
`copyInto(Object[])` | Copies the elements of this vector into an array
`elementAt(int)` | Returns the element at the specified index
`elements()` | Returns an `Enumeration` of the elements
`ensureCapacity(int)` | Ensures that the `Vector` has the specified capacity
`firstElement()` | Returns the first element of the `Vector`
`indexOf(Object)` | Returns the index of the first occurrence of the specified object within the `Vector`
`indexOf(Object, int)` | Returns the index of the specified object within the `Vector`, starting the search at the index specified and proceeding toward the end of the `Vector`
`insertElementAt(Object, int)` | Inserts an object at the index specified
`isEmpty()` | Returns `true` if the `Vector` is empty
`lastElement()` | Returns the last element of the `Vector`
`lastIndexOf(Object)` | Returns the index of the last occurrence of the specified object within the `Vector`
`lastIndexOf(Object, int)` | Returns the index of the specified object within the `Vector`, starting the search at the index specified and proceeding toward the beginning of the `Vector`
`removeAllElements()` | Removes all elements of the `Vector`
`removeElement(Object)` | Removes the specified object from the `Vector`
`removeElementAt(int)` | Removes the element with the specified index
`setElementAt(Object, int)` | Stores the object at the specified index in the `Vector`
`setSize(int)` | Sets the size of the `Vector`
`size()` | Returns the number of elements in the `Vector`
`toString()` | Converts the `Vector` to a string
`trimToSize()` | Trims the `Vector`'s capacity down to the specified size
### The Stack Class The stack data structure is key to many programming efforts, ranging from building compilers to solving mazes. The `Stack` class in the Java library implements a Last In, First Out (LIFO) stack of objects. Even though they are based on (that is, they extend) the `Vector` class, `Stack` objects are typically not accessed in a direct fashion. Instead, values are pushed onto and popped off the top of the stack. The net effect is that the values most recently pushed are the first to pop. The `Stack1` code in Listing 11.9 pushes strings onto the stack and then retrieves them. The strings end up printed in the reverse order from which they were stored. #### Listing 11.9. Stack1.java: A sample Stack program.
    import java.io.DataInputStream;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.Stack;
    import java.util.StringTokenizer;
    class Stack1 {
        public static void main(String args[])
            throws java.io.IOException
        {
            BufferedReader dis=new BufferedReader(new InputStreamReader(System.in));
            System.out.println("Enter a sentence: ");
            String s=dis.readLine();
            StringTokenizer st=new StringTokenizer(s);
            Stack stack=new Stack();
            while (st.hasMoreTokens())
                stack.push(st.nextToken());
            while (!stack.empty())
                System.out.print((String)stack.pop()+" ");
            System.out.println();
        }
    }
The output from this program looks like this:
    Enter a sentence:
    The quick brown fox jumps over the lazy dog
    dog lazy the over jumps fox brown quick The
Even though `Stack` objects normally are not accessed in a direct fashion, it is possible to search the `Stack` for a specific value using the `search()` method. `search()` accepts an object to find and returns the distance from the top of the `Stack` where the object was found. It returns `-1` if the object is not found. The method `peek()` returns the top object on the `Stack` without actually removing it from the `Stack`. The `peek()` method throws an `EmptyStackException` if the stack has no items. Table 11.12 summarizes the complete interface of the `Stack` class. #### Table 11.12. The methods available in the Stack interface.
Method | Description
| Constructor
`Stack()` | Constructs an empty `Stack`
| Methods
`empty()` | Returns `true` if the `Stack` is empty
`peek()` | Returns the top object on the `Stack` without removing the element
`pop()` | Pops an element off the `Stack`
`push(Object)` | Pushes an element onto the `Stack`
`search(Object)` | Finds an object on the `Stack`
### The Dictionary Class The `Dictionary` class is an abstract class used as a base for the `Hashtable` class. It implements a data structure that allows a collection of key and value pairs to be stored. Any type of object can be used for the keys or the values. Typically, the keys are used to find a particular corresponding value. Because the `Dictionary` class is an abstract class that cannot be used directly, the code examples presented in this section cannot actually be run. They are presented only to explain the purpose and use of the methods declared by this class. The following code would, hypothetically, be used to create a `Dictionary` with these values:
    Dictionary products = new Dictionary();
    products.put(new Integer(342), "Widget");
    products.put(new Integer(124), "Gadget");
    products.put(new Integer(754), "FooBar");
The `put()` method is used to insert a key and value pair into the `Dictionary`. Both arguments must be derived from the class `Object`. The key is the first argument and the value is the second argument. A value can be retrieved using the `get()` method and a specific key to be found. `get()` returns the `null` value if the specified key is not found. Here's an example:
    String name = products.get(new Integer(124));
    if (name != null) {
        System.out.println("Product name for code 124 is " + name);
    }
Although an individual object can be retrieved with the `get()` method, it is sometimes necessary to access all the keys or all the values. Two methods, `keys()` and `elements()`, return `Enumeration`s that can be used to access the keys and the values. Table 11.13 summarizes the complete interface of the `Dictionary` class. #### Table 11.13. The methods available in the Dictionary interface.
Method | Description
| Constructor
`Dictionary()` | Constructs an empty `Dictionary`
| Methods
`elements()` | Returns an `Enumeration` of the values
`get(Object)` | Returns the object associated with the specified key
`isEmpty()` | Returns `true` if the `Dictionary` has no elements
`keys()` | Returns an `Enumeration` of the keys
`put(Object, Object)` | Stores the specified key and value pair in the `Dictionary`
`remove(Object)` | Removes an element from the `Dictionary` based on its key
`size()` | Returns the number of elements stored
### The Hashtable Class The hash table data structure is very useful when searching for and manipulating data. You should use the `Hashtable` class if you will be storing a large amount of data in memory and then searching it. The time needed to complete a search of a hash table is decidedly less than what it takes to search a `Vector`. Of course, for small amounts of data, it doesn't make much difference whether you use a hash table or a linear data structure, because the overhead time is much greater than any search time would be. See the following sidebar for more information about search times in the different classes. Hash table organization is based on keys, which are computed based on the data being stored. For example, if you want to insert a number of words into a hash table, you can base your key on the first letter of the word. When you come back later to search for a word, you can then compute the key for the item being sought. By using this key, search time is drastically reduced because the items are stored based on the value of their respective key. The `Hashtable` class implements a hash table storage mechanism for storing key and value pairs. Hash tables are designed to quickly locate and retrieve stored information by using a key. Keys and values can be of any object type, but the key object's class must implement the `hashCode()` and `equals()` methods. SEARCH TIMES Big "O" notation is used to measure the "worst case scenario" time requirements in terms of searching while using different data structures. Linear searching, such as that used in the `Vector` class, is O(n); hash table searching is O(log n). This means that for a large number of objects, you can save a lot of search time when you use a hash table because the log of a number is always less than the number itself. If you will be doing a large amount of searching through data, a hash table is likely to be much more efficient. The sample `Hashtable1` in Listing 11.10 creates a `Hashtable` object and stores 10 key and value pairs using the `put()` method. It then uses the `get()` method to return the value corresponding to a key entered by the user. #### Listing 11.10. Hashtable1.java: A sample Hashtable program.
    import java.io.DataInputStream;
    import java.lang.Integer;
    import java.lang.Math;
    import java.util.Random;
    import java.util.Hashtable;
    class Hashtable1 {
        public static void main(String args[])
            throws java.io.IOException
        {
            DataInputStream dis=new DataInputStream(System.in);
            int numElements=10;
            String keys[]={"Red","Green","Blue","Cyan","Magenta",
                "Yellow","Black","Orange","Purple","White"};
            Hashtable ht;
            Random randGen=new Random();
            ht=new Hashtable(numElements*2);
            for (int i=0;i<numElements;i++)
                ht.put(keys[i],new Integer(Math.abs(
                    randGen.nextInt())%numElements));
            System.out.println(ht.toString());
            String keyValue;
            System.out.println("Which key to find? ");
            keyValue=dis.readLine();
            Integer value=(Integer)ht.get(keyValue);
            if (value!=null) System.out.println(keyValue+" = "+value);
        }
    }
The output from this program looks like this:
    {Cyan=4, White=0, Magenta=4, Red=5, Black=3,
    Green=8, Purple=3, Orange=4, Yellow=2, _Blue=6}
    Which key to find?
    Red
    Red = 5
In addition to the `get()` method, the `contains()` and `containsKey()` methods can be used to search for a particular value or key. Both return `true` or `false` depending on whether the search was successful. The `contains()` method must perform an exhaustive search of the table and is not as efficient as the `containsKey()` method, which can take advantage of the hash table's storage mechanism to find the key quickly. Because hash tables must allocate storage for more data than actually is stored, a measurement called the load factor indicates the number of used storage spaces as a fraction of the total available storage spaces. The load factor is expressed as a value between 0 and 100 percent. Typically, the load factor should not be higher than about 50 percent for efficient retrieval of data from a hash table. When specifying the load factor in a program, use a fractional value in the range 0.0 to 1.0 to represent load factors in the range 0 to 100 percent. Hash tables can be constructed in three different ways: by specifying the desired initial capacity and load factor; by specifying only the initial capacity; or by specifying neither the initial capacity nor the load factor. If the load factor is not specified, the `Hashtable` is rehashed into a larger table when it is full--otherwise, it is rehashed when it exceeds the load factor. The constructors throw an `IllegalArgumentException` if the initial capacity is less than or equal to zero, or if the load factor is less than or equal to zero. The `clone()` method can be used to create a copy (a clone) of the `Hashtable`. However, it creates a shallow copy of the `Hashtable`, which means that the keys and values themselves are not clones. This local method overrides the inherited `clone()` method. CAUTION: The `clone()` method is a relatively expensive operation to perform in terms of memory usage and execution time. Because the new `Hashtable` still refers directly to the objects (keys and values) stored in the old table, use caution to avoid making changes that will disrupt the original `Hashtable`. The `Hashtable` class extends the `java.util.Dictionary` class and implements the `java.lang.Cloneable` interface. Table 11.14 summarizes the methods of the `Hashtable` class. #### Table 11.14. The methods available in the Hashtable interface.
Method | Description
| Constructors
`Hashtable()` | Constructs an empty `Hashtable`
`Hashtable(int)` | Constructs an empty `Hashtable` with the specified capacity
`Hashtable(int, float)` | Constructs an empty `Hashtable` with the given capacity and load factor
| Methods
`clear()` | Deletes all elements from the `Hashtable`
`clone()` | Creates a clone of the `Hashtable`
`contains(Object)` | Returns `true` if the specified object is an element of the `Hashtable`
`containsKey(Object)` | Returns `true` if the `Hashtable` contains the specified key
`elements()` | Returns an `Enumeration` of the `Hashtable`'s values
`get(Object)` | Returns the object associated with the specified key
`isEmpty()` | Returns `true` if the `Hashtable` has no elements
`keys()` | Returns an `Enumeration` of the keys
`put(Object, Object)` | Stores the specified key and value pair in the `Hashtable`
`rehash()` | Rehashes the contents of the table into a bigger table
`remove(Object)` | Removes an element from the `Hashtable` based on its key
`size()` | Returns the number of elements stored
`toString()` | Converts the contents to a very long string
### The Properties Class The `Properties` class is what enables end-users to customize their Java program. For example, you can easily store values such as foreground colors, background colors, font defaults, and so on and then have those values available to be reloaded. This arrangement is most useful for Java applications, but you can also implement it for applets. If you have an applet that is regularly used by multiple users, you can keep a properties file on your server for each different user; the properties file is accessed each time that user loads the applet. The `Properties` class is a `Hashtable`, which can be repeatedly stored and restored from a stream. It is used to implement persistent properties. The `Properties` class also allows for an unlimited level of nesting, by searching a default property list if the required property is not found. The fact that this class is an extension of the `Hashtable` class means that all methods available in the `Hashtable` class are also available in the `Properties` class. The sample program `Properties1` in Listing 11.11 creates two properties lists. One is the default property list and the other is the user-defined property list. When the user property list is created, the default `Properties` object is passed. When the user property list is searched, if the key value is not found, the default `Properties` list is searched. #### Listing 11.11. Properties1.java: A sample Properties program.
    import java.io.DataInputStream;
    import java.lang.Integer;
    import java.util.Properties;
    class Properties1 {
        public static void main(String args[])
            throws java.io.IOException
        {
            int numElements=4;
            String defaultNames[]={"Red","Green","Blue","Purple"};
            int defaultValues[]={1,2,3,4};
            String userNames[]={"Red","Yellow","Orange","Blue"};
            int userValues[]={100,200,300,400};
            DataInputStream dis=new DataInputStream(System.in);
            Properties defaultProps=new Properties();
            Properties userProps=new Properties(defaultProps);
            for (int i=0;i<numElements;i++){
                defaultProps.put(defaultNames[i],
                    Integer.toString(defaultValues[i]));
                userProps.put(userNames[i],
                    Integer.toString(userValues[i]));
            }
            System.out.println("Default Properties");
            defaultProps.list(System.out);
            System.out.println("\nUser Defined Properties");
            userProps.list(System.out);
            String keyValue;
            System.out.println("\nWhich property to find? ");
            keyValue=dis.readLine();
            System.out.println("Property '"+keyValue+"' is '"+
                userProps.getProperty(keyValue)+"'");
        }
    }
Notice that the `getProperties()` method is used instead of the inherited `get()` method. The `get()` method searches only the current `Properties` object. The `getProperties()` method must be used to search the default `Properties` list. An alternative form of the `getProperties()` method has a second argument: a `Properties` list that is to be searched instead of the default specified when the `Properties` object was created. The `propertyNames()` method can be used to return an `Enumeration`, which can be used to index all the property names. This `Enumeration` includes the property names from the default `Properties` list. Likewise, the `list()` method, which prints the `Properties` list to the standard output, lists all the properties of the current `Properties` object and those in the default `Properties` object. `Properties` objects can be written to and read from a stream using the `save()` and `load()` methods. In addition to the output or input stream, the `save()` method has an additional string argument that is written at the beginning of the stream as a header comment. Table 11.15 summarizes the methods of the `Properties` class. #### Table 11.15. The variables and methods available in the Properties interface.
Variable | Description
`defaults` | Default `Properties` list to search
| Constructors
`Properties()` | Constructs an empty property list
`Properties(Properties)` | Constructs an empty property list with the specified default
| Methods
`getProperty(String)` | Returns a property given the key
`getProperty(String, String)` | Returns a property given the specified key and default
`list(PrintStream)` | Lists the properties to a stream for debugging
`load(InputStream)` | Reads the properties from an `InputStream`
`propertyNames()` | Returns an `Enumeration` all the keys
`save(OutputStream, String)` | Writes the properties to an `OutputStream`
### The Observable Class The `Observable` class acts as a base class for objects you want to have observed by other objects that implement the `Observer` interface. An `Observable` object can notify its `Observer`s whenever the `Observable` object is modified using the `notifyObservers()` method. This method accomplishes the notification by invoking the `update()` method of all its `Observer`s, optionally passing a data object that is passed to `notifyObservers()`. `Observable` objects can have any number of `Observer`s. Table 11.16 summarizes the complete interface of the `Observable` class. #### Table 11.16. The methods available in the Observable interface.
Method | Description
| Constructor
`Observable()` | Constructs an instance of the `Observable` class.
| Methods
`addObserver(Observer)` | Adds an `Observer` to the observer list
`clearChanged()` | Clears an observable change
`countObservers()` | Returns the number of `Observer`s
`deleteObserver(Observer)` | Deletes an `Observer` from the observer list
`deleteObservers()` | Deletes all `Observer`s from the observer list
`hasChanged()` | Returns `true` if an observable change has occurred
`notifyObservers()` | Notifies all `Observer`s when an observable change has occurred
`notifyObservers(Object)` | Notifies all `Observer`s of a specific observable change
`setChanged()` | Sets a flag to indicate that an observable change has occurred
## Summary This chapter described the classes that make up the Java utilities package. This package provides complete implementations of the basic data structures and some of the most useful data types (other than the fundamental numeric types) needed by programmers. Many of the data types and data structures you will develop using Java will be based on the classes found in the utilities package. For smaller applets, many of these classes are not necessary. However, as your applets increase in complexity, you will find these classes to be very useful. In any case, this chapter has been a good starting point for understanding the utility of these important Java classes and for understanding how to use them effectively.
| ©Copyright, Macmillan Computer Publishing. All rights reserved.