The use of Java hashtable

Source: Internet
Author: User
Tags abstract hash int size integer tostring wrapper

The

Vector allows us to select from a range of objects with a number, so it actually associates numbers with objects. But what if we want to choose a series of objects based on other criteria? The stack is an example of this: its selection criterion is "The last thing to push onto the stack." This "Select from a series of objects" concept can also be called a "map", "dictionary" or "associative array." Conceptually, it looks like a vector, but instead of finding objects by numbers, you look for them with another object! This is usually part of an important process in a program.
in Java, this concept is specifically reflected in the abstract class dictionary. The interface of this class is very intuitive size () tells us how many elements it contains, IsEmpty () to determine whether the element is included (true), and put (object key, Object value) to add a value (what we want), and associates it with the same key (what you want to search for it), the Get (object key) Gets the value that corresponds to a key, and the Remove (object key) is used to remove the key-value pair from the list. You can also use enumeration techniques: the keys () produce an enumeration of keys (enumeration), and elements () produces an enumeration of all values. This is the whole of a dictionary (dictionary). The
Dictionary implementation process is not cumbersome. Here is an easy way to use two vectors, one to hold the key, and the other to hold the value:
 

: Assocarray.java//Simple version of a Dictionary import java.util.*;
  public class Assocarray extends Dictionary {private vector keys = new vector ();
  Private vector values = new vector ();
  public int size () {return keys.size ();}
  public Boolean IsEmpty () {return keys.isempty ();
    The public object is put (object key, Object value) {keys.addelement (key);
    Values.addelement (value);
  Return key;
    The public object get (object key) {int index = KEYS.INDEXOF (key);
    IndexOf () Returns-1 if key not found:if (index = = 1) return null;
  Return Values.elementat (index);
    The public object remove (object key) {int index = KEYS.INDEXOF (key);
    if (index = = 1) return null;
    Keys.removeelementat (index);
    Object returnval = values.elementat (index);
    Values.removeelementat (index);
  return returnval;
  Public enumeration keys () {return keys.elements ();
  Public enumeration elements () {return values.elements (); }//TesT it:public static void Main (string[] args) {assocarray AA = new Assocarray (); for (char c = ' a '; c <= ' z '; c + +) Aa.put (string.valueof (c), string.valueof (c). Toupperca
    SE ());
    Char[] ca = {' A ', ' e ', ' I ', ' o ', ' u '}; for (int i = 0; i < ca.length i++) System.out.println ("Uppercase:" + aa.get (string.valueof (ca[i)))
  ; }
} ///:~


The first problem we notice in the definition of Assocarray is that it "expands" the dictionary. This means that Assocarray belongs to a type of dictionary, so it can make the same request as dictionary. If you want to build your own dictionary and do it here, all you have to do is populate all the methods that are in dictionary (and you must overwrite all the methods because they--except for the builder--are abstract).
Vector key and value are linked by a standard index number. That is, if you call put () with a key of "roof" and a value of "blue"-suppose we are going to associate the parts of a house with their paint colors, and there are already 100 elements in the Assocarray, then "Roof" will have 101 key elements, and " Blue "has 101 value elements. and pay attention to get (), if we pass "roof" as a key, it produces the index number of the Keys.index.Of (), and then uses that index number to generate the value within the relevant value vector.
The test in main () is very simple; it simply converts lowercase characters to uppercase characters, which is clearly useful in more efficient ways. But it reveals to us the powerful function of Assocarray.
The standard Java library contains only one variant of dictionary, named Hashtable (hash table, comment ③). The Java hash table has the same interface as Assocarray (since both are inherited from dictionary). But one aspect reflects the difference: efficiency of implementation. If you think about what you have to do for a get (), you'll find that the search key is much slower in a vector. But using a hash table at this point can speed up a lot. Instead of using lengthy linear search techniques to find a key, you use a special value called hash code. The hash code gets the information in the object and converts it to the "relatively unique" integer (int) of that object. All objects have a hash code, and Hashcode () is a method of the root class object. Hashtable gets the hashcode () of the object, and then uses it to quickly find the key. This allows for a significant increase in performance (④). The specifics of the hash table are beyond the scope of this book (⑤)--you just need to know that the hash table is a Fast "dictionary" (Dictionary), and that the dictionary is a very useful tool.

③: If you plan to use RMI (detailed in chapter 15th), be aware that you will encounter a problem when you place a remote object in a hash table (see Core Java, author Conrell and Horstmann,prentice-hall published in 1997)
④: If this speed increase still does not meet your performance requirements, you can even write your own hashtable routines, thus further speeding up the search process of the table. This avoids the time delay between modeling with object or the synchronization process built into a Java class Library hash table routine.
⑤: The best reference book I Know is "practical algorithms for programmers," the author of Andrew Binstock and John Rex,addison-wesley published in 1995.

As an example of applying a hash table, consider using a program to test the randomness of the Java Math.random () method. Ideally, it should produce a series of perfect random distribution numbers. But to verify this, we need to generate a large number of random numbers and then calculate how many numbers fall in different ranges. A hash table can greatly simplify this work because it can associate objects with objects (at which point the values generated by Math.random () are associated with the number of occurrences of those values). As shown below:

: Statistics.java
//Simple demonstration of Hashtable
import java.util.*;

Class Counter { 
  int i = 1; 
  Public String toString () {return 
    integer.tostring (i); 
  }
}

Class Statistics {public
  static void Main (string[] args) {
    Hashtable ht = new Hashtable ();
    for (int i = 0; I < 10000 i++) {
      //produce a number between 0 and:
      integer r = 
        new Integer ((int) (Mat H.random ());
      if (Ht.containskey (R))
        ((Counter) Ht.get (R)). i++;
      else
        Ht.put (R, New Counter ());
    SYSTEM.OUT.PRINTLN (HT);
  }
///:~


In main (), each time a random number is generated, it is encapsulated in an integer object so that the handle can be used with the hash table (you cannot use the base data type for a collection, only the object handle). The Containkey () method checks whether the key is already in the collection (that is, the number has been found before?). If it is already in the collection, The Get () method obtains the value associated with that key, which is an counter (counter) object. The value I in the counter will then increase by 1, indicating that this particular random number appears again.
If the key has not been discovered before, the method put () will still have a new "key-value" pair built into the hash list. At the beginning of the creation, counter automatically initializes its own variable I to 1, which marks the first occurrence of the random number.
To display a hash table, simply print it out. The Hashtable ToString () method iterates through all key-value pairs and calls toString () for each pair. The Integer ToString () is defined beforehand to see the toString used by the counter. The results of one run (some lines added) are as follows:

{19=526, 18=533, 17=460, 16=513, 15=521, 14=495, 13=512, 12=483, 11=488, 10=487, 9=514, 8=523, 7=497, 6=487, 5=480
 , 4=489, 3=509, 2=503, 1=475,
 0=505}

You may wonder whether the counter class is necessary, and it does not seem to have the functionality to encapsulate the class integer at all. Why not int or integer? In fact, because all collections can hold only object handles, integers cannot be used at all. Once you've learned about collections, the concept of encapsulating classes may be easier to understand because you can't put any of the basic data types into a collection. However, the only thing we can do with the Java wrapper is initialize it to a specific value and then read that value. In other words, once the wrapper object has been created, there is no way to change a value. This makes the integer wrapper meaningless to solve our problem, so we have to create a new class that meets our requirements.

1. Create a "critical" class
in the previous example, we use a standard library class (Integer) as a key for Hashtable. As a key, it works well because it already has all the conditions to run correctly. But when using a hash table, once we create our own class as a key, we run into a very common problem. For example, suppose a set of weather forecasting systems matches the groundhog (Soil-rat) object into a prediction (forecast). This looks very intuitive: we create two classes, then use Groundhog as a key and use prediction as a value. As follows:
 

//: Springdetector.java//Looks plausible, but doesn ' t work right. Import java.util.*;
  class Groundhog {int ghnumber;

Groundhog (int n) {ghnumber = n;}}
  Class Prediction {Boolean shadow = Math.random () > 0.5;
    Public String toString () {if (shadow) return "Six more weeks of winter!";
  else return "Early spring!";
    } public class Springdetector {public static void main (string[] args) {Hashtable ht = new Hashtable ();
    for (int i = 0; i < i++) Ht.put (new Groundhog (i), new Prediction ());
    SYSTEM.OUT.PRINTLN ("HT =" + HT + "\ n");
    System.out.println ("Looking up prediction for Groundhog #3:");
    Groundhog GH = new Groundhog (3);
  if (Ht.containskey (GH)) System.out.println (prediction) ht.get (GH); }
} ///:~

Each groundhog has an identification number, so red looks for a prediction in the hash table and simply instructs it to "tell me the prediction associated with Groundhog Number 3." The Prediction class contains a Boolean value, initialized with Math.random (), and a ToString () explains the result for us. In main (), populate a hash table with groundhog and the prediction associated with them. The hash table is printed so that we can see that they are actually populated. Subsequently, a groundhog with an identification number of 3 is used to find the #3对应的预报 with the groundhog. The
appears to be very simple, but it is not feasible in practice. The problem is that groundhog is inherited from the generic object root class (if the underlying class was not specified, then all classes are ultimately inherited from object). In fact, the hash code of each object is generated using the Hashcode () method of object, and by default only its object's address is used. Therefore, the first instance of Groundhog (3) does not produce a hash code equal to the second instance of Groundhog (3), and we retrieve it with a second instance.
You might think that all you have to do at this point is to properly overwrite hashcode (). But doing this is still not possible unless you do another thing: the Equals () that covers the part of object. This method is used when the hash table attempts to determine whether our key is equal to a key in the list. Similarly, the default object.equals () simply compares the object address, so a groundhog (3) does not equal another groundhog (3).
Therefore, in order to use your class as a key in a hash table, you must overwrite both hashcode () and Equals () as shown below:
 

//: Springdetector2.java//If You create a class so ' s used as a key in//a Hashtable, your must ov
Erride hashcode ()//And Equals ().

Import java.util.*;
  Class Groundhog2 {int ghnumber;
  GROUNDHOG2 (int n) {ghnumber = n;}
  public int hashcode () {return ghnumber;} public boolean equals (Object o) {return (o instanceof Groundhog2) && (Ghnumber = = ((GROUNDHOG2) o). Ghnum
  ber);
    } public class SpringDetector2 {public static void main (string[] args) {Hashtable ht = new Hashtable ();
    for (int i = 0; i < i++) Ht.put (new Groundhog2 (i), new Prediction ());
    SYSTEM.OUT.PRINTLN ("HT =" + HT + "\ n");
    System.out.println ("Looking up prediction for Groundhog #3:");
    Groundhog2 gh = new Groundhog2 (3);
  if (Ht.containskey (GH)) System.out.println (prediction) ht.get (GH); }
} ///:~

Note that this code uses the prediction from the previous example, so Springdetector.java must compile first, or you will get a compile-time error when attempting to compile the Springdetector2.java.
Groundhog2.hashcode () returns the native mouse number as an identifier (in this case, the programmer needs to make sure that no two soil rats coexist with the same ID number). In order to return a unique identifier, there is no need for hashcode (), and the Equals () method must be able to strictly determine whether two objects are equal.
The Equals () method examines two types of checks: whether the object is null, or, if not NULL, whether it is an instance of Groundhog2 (the instanceof keyword is used, which is discussed in detail in chapter 11th). Even if you continue to execute equals (), it should be a Groundhog2. As you can see, this comparison is based on actual ghnumber. This time, once we run the program, we'll see that it finally produces the right output (many Java library classes overwrite the hashcode () and Equals () methods to accommodate what they provide).

2. Attribute: A type of hashtable
In the first example of this book, we used a Hashtable type called properties. In that example, the following line of the procedure:
Properties p = system.getproperties ();
P.list (System.out);
A static method named GetProperties () is invoked to obtain a special properties object that describes some of the characteristics of the system. List () is a method of properties that can send content to any stream output we choose. There is also a save () method that can be used to write a list of properties to a file for later reading with the load () method.
Although the properties class is inherited from Hashtable, it also contains a hash table to hold the list of "default" attributes. So if you don't find an attribute in the main list, the default properties are automatically searched.
Properties can also be used in our programs (in the 17th chapter, the Classscanner.java is an example). In the user documentation for the Java library, you can often find more and more detailed descriptions.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.