What is Hashtable?
- Hashtable is a synchronous implementation of map interface based on hash table
- The key of the element in the Hashtable is unique, and the value can be repeated
- The key and value of the elements in the Hashtable are not allowed to be null, and if NULL is encountered, the NullPointerException is returned
- The elements in the Hashtable are unordered
public class hashtable<k,v> extends dictionary<k,v> implements Map<k,v>, Cloneable, java.io.serializable{}
Hashtable and HashMap, the same is the data structure of the chain table hash, from the source we can see, Hashtable inherits from the dictionary class, the implementation of the map, cloneable,serializable interface
- The dictionary class is the abstract parent class for any class that can map keys to corresponding values, each of which is an object
- Dictionary source Note that Dictionary This class is obsolete, the new implementation class should implement the map interface
Hashtable member variables
- Table: A entry[] array type, and entry (explained in HashMap) is a one-way list. The hash table's "Key-value Key-value pairs" are stored in the entry array.
- The size of the count:hashtable, which is the number of key-value pairs saved by Hashtable
- Threshold:hashtable threshold for determining if hashtable capacity needs to be adjusted, threshold value = (capacity * load factor)
- Loadfactor: Load factor
- Modcount: Used to implement the fail-fast mechanism
Hashtable construction method
Hashtable provides a total of 4 construction methods
- Public Hashtable (int initialcapacity, float loadfactor): Constructs a new empty hash table with the specified initial capacity and specified load factor
- Public Hashtable (int initialcapacity): Constructs a new empty hash table with the specified initial capacity and default load factor (0.75)
- Public Hashtable (): default constructor with a capacity of 11 and a load factor of 0.75
- Public Hashtable (map< extends K,? extends V> T): Constructs a new hash table with the same mapping as a given map
Public synchronized v put (K key, V value) {//ensure value is not NULL if (value = = null) {throw new Nullpointerexcepti On (); }//Make sure key is not in Hashtable//first, the hash value of key is computed by hash method, and the index value is calculated to determine its position in table[]//second, the linked list that iterates over the index position, if the linked list at that location exists the same key, Change value, return the old value Entry tab[] = table; int hash = hash (key); int index = (hash & 0x7FFFFFFF)% Tab.length; for (entry<k,v> e = Tab[index]; E! = null; e = e.next) {if (E.hash = = hash) && e.key.equals (key)) {V old = E.value; E.value = value; return old; }} modcount++; if (count >= threshold) {//If the threshold is exceeded, the rehash operation is rehash (); tab = table; hash = hash (key); Index = (hash & 0x7FFFFFFF)% Tab.length; }//Insert value, return null entry<k,v> e = Tab[index]; Create a new Entry node, insert the new Entry into the index position of the Hashtable, and set E as the next element of the new Entry tab[index] = new entry<> (hash, key, value, E); count++; return null;}
The stored process is as follows:
- Determines whether value is empty, throws an exception if it is empty
- Calculates the hash value of key and obtains the position of key in the table array based on the hash value index
If the Table[index] element is empty, insert the element into the Table[index] position
If the Table[index] element is not empty, then the linked list is traversed, and if the same key is encountered, the new value replaces the old value and returns the old value, otherwise inserts the element into the chain header, returning NULL
Acquisition of Hashtable
Public synchronized V get (Object key) { Entry tab[] = table; int hash = hash (key); int index = (hash & 0x7FFFFFFF)% Tab.length; for (entry<k,v> e = Tab[index]; E! = null; e = e.next) { if (E.hash = = hash) && e.key.equals (key)) { C6/>return e.value; } } return null;}
The process is obtained as follows:
1. The hash value of key is obtained by hash () method.
2, according to the hash value to get index
3. Iterate the linked list, return the corresponding value of the matching key, and return NULL if not found
Hashtable traversal mode
There are 4 ways to traverse the Hashtable:
1. Use keys () enumeration<string> en1 = Table.keys (); while (En1.hasmoreelements ()) { en1.nextelement ();} 2, using elements () enumeration<string> en2 = Table.elements (); while (En2.hasmoreelements ()) { en2.nextelement ();} 3, use KeySet () iterator<string> it1 = Table.keyset (). Iterator (); while (It1.hasnext ()) { it1.next ();} 4, using EntrySet () iterator<entry<string, string>> it2 = Table.entryset (). Iterator (); while (It2.hasnext ()) { it2.next ();}
The difference between Hashtable and HashMap
Hashtable |
HashMap |
Method is synchronous. |
Method is non-synchronous |
Based on the dictionary class |
Based on Abstractmap, and the implementation of ABSTRACTMAP based on map interface |
Both key and value are not allowed to be NULL, and NULL is encountered, directly returning NullPointerException |
Both key and value are allowed to be null, and when a key is null, the Putfornullkey method is called to process and the value is not processed |
Hash array default size is 11, the expansion is old*2+1 |
The default size of the hash array is 16, and must be a 2 index |
Problems with multithreading
1, if the multi-threaded synchronization is involved, it is recommended to use Hashtable
2, not related to multi-threaded synchronization, it is recommended to use HashMap
3. There is a static method in the Collections class: Synchronizedmap (), which creates a thread-safe Map object and returns it as a encapsulated object
Synchronizedmap () is actually the method of the map to add a layer of synchronization lock, from the source can be seen
Collections.synchronizedmap (map<k, v>) public static <K,V> map<k,v> Synchronizedmap (map<k,v > m) {return new synchronizedmap<k,v> (m);} private static class synchronizedmap<k,v> implements Map<k,v>, Serializable {private static final long ser Ialversionuid = 1978198479659022715L; Private final map<k,v> m; backing Map//Sync lock final Object mutex; Object on which to synchronize Synchronizedmap (map<k,v> m) {if (m==null) throw new Nullpoin Terexception (); THIS.M = m; Take this as the lock monitor so that any thread accesses his method to get the monitor. Mutex = this; } synchronizedmap (map<k,v> m, Object mutex) {this.m = m; This.mutex = Mutex; } public int size () {synchronized (mutex) {return m.size ();} }//Rewrite map's Emty method public Boolean IsEmpty () {synchronized (mutex) {return m.isempty ();} } public boolean ContainsKey (Object key) {SynchroniZed (Mutex) {return M.containskey (key);} } public boolean Containsvalue (Object value) {synchronized (mutex) {return m.containsvalue (value);} } public V get (Object key) {synchronized (mutex) {return m.get (key);} } public V put (K key, V value) {synchronized (mutex) {return M.put (key, value);} } public V Remove (Object key) {synchronized (mutex) {return m.remove (key);} } public void Putall (map<? extends K,? extends V> Map) {synchronized (mutex) {M.putall (MAP);} } public void Clear () {synchronized (mutex) {m.clear ();} } private transient set<k> keySet = null; private transient set<map.entry<k,v>> entryset = null; private transient collection<v> values = null; Override KeySet method public set<k> KeySet () {synchronized (mutex) {if (keyset==null)// The mutex is passed to Synchronizedset so that the lock is also acquired for the set internal operation. KeySet = new synchronizedset<k> (M.keyset (), mutex); return keySet; }} public set<map.entry<k,v>> EntrySet () {synchronized (mutex) {if (entryset==null) EntrySet = new Synchronizedset<map.entry<k,v>> (M.entryset (), mutex); return entryset; }} public collection<v> values () {synchronized (mutex) {if (values==null) V Alues = new Synchronizedcollection<v> (M.values (), mutex); return values; }} public Boolean equals (Object O) {synchronized (mutex) {return m.equals (o);} } public int hashcode () {synchronized (mutex) {return M.hashcode ();} } public String toString () {synchronized (mutex) {return m.tostring ();} } private void WriteObject (ObjectOutputStream s) throws IOException {synchronized (mutex) {S.defaultwriteobject ( );} }}
In-depth understanding of the---------Hashtable collection of the Java Collection framework