Hashtable of Java source code

Source: Internet
Author: User
Tags rehash

Hashtable of Java source code

1. Hashtable Overview

Class implements a hash table, which maps the key-key object to the corresponding value object. Both key and value are requiredNon-null. To successfully store and obtain objects in a hash table, the hashCode and equals methods must be implemented for the objects used as keys.

Hashtable is thread-synchronized, but non-thread-synchronized HashMap can replace it completely.

If thread security is not required, use HashMap instead;

To ensure thread security and high concurrency, use java. util. concurrent. ConcurrentHashMap instead.

Ii. Hashtable Data Structure

Like HashMap before jdk1.8, Hashtable usesArray + linked list.

/*** Hashtable array conflict link node */private static class Entry
 
  
Implements Map. Entry
  
   
{Final int hash; final K key; V value; Entry
   
    
Next; // The next node protected Entry (int hash, K key, V value, Entry
    
     
Next) {this. hash = hash; this. key = key; this. value = value; this. next = next ;}@ SuppressWarnings ("unchecked") protected Object clone () {return new Entry <> (hash, key, value, (next = null? Null: (Entry
     
      
) Next. clone ();} // Map. entry Ops public K getKey () {return key;} public V getValue () {return value;} public V setValue (V value) {if (value = null) throw new NullPointerException (); V oldValue = this. value; this. value = value; return oldValue;} public boolean equals (Object o) {if (! (O instanceof Map. Entry) return false; Map. Entry
      E = (Map. Entry
      ) O; return (key = null? E. getKey () = null: key. equals (e. getKey () & (value = null? E. getValue () = null: value. equals (e. getValue ();} public int hashCode () {return hash ^ Objects. hashCode (value);} public String toString () {return key. toString () + "=" + value. toString ();}}
     
    
   
  
 

Iii. Hashtable source code

1. header file

package java.util;import java.io.*;import java.util.concurrent.ThreadLocalRandom;import java.util.function.BiConsumer;import java.util.function.Function;import java.util.function.BiFunction;

2. Implementation and inheritance

public class Hashtable
 
  extends Dictionary
  
   implements Map
   
    , Cloneable, java.io.Serializable
   
  
 

3. Attributes

/*** Hash table array */private transient Entry
 [] Table;/*** number of elements stored in the array */private transient int count;/*** threshold value, * threshold = capacity * loadFactor */private int threshold;/*** load factor */private float loadFactor; /*** number of modifications * use the fail-fast mechanism */private transient int modCount = 0;


 

4. constructor and Method

The main difference between this part and HashMap is the hash function algorithm.

Here, we use the typical division of residue method:

 

int index = (hash & 0x7FFFFFFF) % tab.length;

 

This part of the constructor and method is not much different from HashMap, but synchronized is added before the method to synchronize the method.

/*** Constructor 1: * use the specified capacity + specified load factor to construct */public Hashtable (int initialCapacity, float loadFactor) {if (initialCapacity <0) throw new IllegalArgumentException ("Illegal Capacity:" + initialCapacity); if (loadFactor <= 0 | Float. isNaN (loadFactor) throw new IllegalArgumentException ("Illegal Load:" + loadFactor); if (initialCapacity = 0) initialCapacity = 1; this. loadFactor = loadFactor; table = new Entry
 [InitialCapacity]; threshold = (int) Math. min (initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);}/*** Construction Method 2: * specify capacity + default loading Factor construction */public Hashtable (int initialCapacity) {this (initialCapacity, 0.75f);}/*** constructor 3: * use default capacity 11 + default load factor */public Hashtable () {this (11, 0.75f);}/*** Construction Method 4: * use Map to construct */public Hashtable (Map
 T) {this (Math. max (2 * t. size (), 11), 0.75f); putAll (t);}/*** return capacity size */public synchronized int size () {return count ;} /*** empty judge */public synchronized boolean isEmpty () {return count = 0;}/*** returns the Enumeration set of all key values */public synchronized Enumeration
 
  
Keys () {return this.
  
   
GetEnumeration (KEYS);}/*** returns an Enumeration set of all value values */public synchronized Enumeration
   
    
Elements () {return this.
    
     
GetEnumeration (VALUES);}/*** determines whether the Object contains the value */public synchronized boolean contains (Object value) {if (value = null) {throw new NullPointerException ();} Entry
     Tab [] = table; for (int I = tab. length; I --> 0;) {for (Entry
     E = tab [I]; e! = Null; e = e. next) {if (e. value. equals (value) {return true ;}} return false;}/*** determine whether to include the value Object */public boolean containsValue (Object value) {return contains (value);}/*** determines whether the Object contains the key value */public synchronized boolean containsKey (Object key) {Entry
     Tab [] = table; int hash = key. hashCode (); int index = (hash & 0x7fffff) % tab. length; for (Entry
     E = tab [index]; e! = Null; e = e. next) {if (e. hash = hash) & e. key. equals (key) {return true;} return false;}/*** get the value corresponding to the key value */@ SuppressWarnings ("unchecked ") public synchronized V get (Object key) {Entry
     Tab [] = table; int hash = key. hashCode (); int index = (hash & 0x7fffff) % tab. length; for (Entry
     E = tab [index]; e! = Null; e = e. next) {if (e. hash = hash) & e. key. equals (key) {return (V) e. value ;}} return null;}/*** maximum array capacity */private static final int MAX_ARRAY_SIZE = Integer. MAX_VALUE-8;/*** resize (2 * oldCap + 1) */@ SuppressWarnings ("unchecked") protected void rehash () {int oldCapacity = table. length; Entry
     [] OldMap = table; // overflow-conscious code int newCapacity = (oldCapacity <1) + 1; if (newCapacity-MAX_ARRAY_SIZE> 0) {if (oldCapacity = MAX_ARRAY_SIZE) // Keep running with MAX_ARRAY_SIZE buckets return; newCapacity = MAX_ARRAY_SIZE;} Entry
     [] NewMap = new Entry
     [NewCapacity]; modCount ++; threshold = (int) Math. min (newCapacity * loadFactor, MAX_ARRAY_SIZE + 1); table = newMap; for (int I = oldCapacity; I --> 0;) {for (Entry
     
      
Old = (Entry
      
        ) OldMap [I]; old! = Null;) {Entry
       
         E = old; old = old. next; int index = (e. hash & 0x7FFFFFFF) % newCapacity; e. next = (Entry
        
          ) NewMap [index]; newMap [index] = e ;}} private void addEntry (int hash, K key, V value, int index) {modCount ++; Entry
         Tab [] = table; if (count> = threshold) {// Rehash the table if the threshold is exceeded rehash (); tab = table; hash = key. hashCode (); index = (hash & 0x7FFFFFFF) % tab. length;} // Creates the new entry. @ SuppressWarnings ("unchecked") Entry
         
           E = (Entry
          
            ) Tab [index]; tab [index] = new Entry <> (hash, key, value, e); count ++ ;} /***** add element * The original key value exists, and the return value * The original key value does not exist. null */public synchronized V put (K key, V value) {// Make sure the value is not null if (value = null) {throw new NullPointerException ();} // Makes sure the key is not already in the hashtable. entry
           Tab [] = table; int hash = key. hashCode (); int index = (hash & 0x7FFFFFFF) % tab. length; @ SuppressWarnings ("unchecked") Entry
           
             Entry = (Entry
            
              ) Tab [index]; for (; entry! = Null; entry = entry. next) {if (entry. hash = hash) & entry. key. equals (key) {V old = entry. value; entry. value = value; return old ;}} addEntry (hash, key, value, index); return null ;} /*** Delete and return the value to be deleted */public synchronized V remove (Object key) {Entry
             Tab [] = table; int hash = key. hashCode (); int index = (hash & 0x7FFFFFFF) % tab. length; @ SuppressWarnings ("unchecked") Entry
             
               E = (Entry
              
                ) Tab [index]; for (Entry
               
                 Prev = null; e! = Null; prev = e, e = e. next) {if (e. hash = hash) & e. key. equals (key) {modCount ++; if (prev! = Null) {prev. next = e. next;} else {tab [index] = e. next;} count --; V oldValue = e. value; e. value = null; return oldValue;} return null;}/*** Add the elements in the Map */public synchronized void putAll (Map
                T) {for (Map. Entry
                E: t. entrySet () put (e. getKey (), e. getValue ();}/*** clear */public synchronized void clear () {Entry
                Tab [] = table; modCount ++; for (int index = tab. length; -- index> = 0;) tab [index] = null; count = 0;}/*** clone Object */public synchronized Object clone () {try {Hashtable
                T = (Hashtable
                ) Super. clone (); t. table = new Entry
                [Table. length]; for (int I = table. length; I --> 0;) {t. table [I] = (table [I]! = Null )? (Entry
                ) Table [I]. clone (): null;} t. keySet = null; t. entrySet = null; t. values = null; t. modCount = 0; return t;} catch (CloneNotSupportedException e) {// this shouldn't happen, since we are Cloneable throw new InternalError (e);} private
                
                  Enumeration
                 
                   GetEnumeration (int type) {if (count = 0) {return Collections. emptyEnumeration ();} else {return new Enumerator <> (type, false);} // obtain the iterator private
                  
                    Iterator
                   
                     GetIterator (int type) {if (count = 0) {return Collections. emptyIterator ();} else {return new Enumerator <> (type, true );}} // Views/*** Each of these fields are initialized to contain an instance of the * appropriate view the first time this view is requested. the views are * stateless, so there's no reason to create more than one of each. */private transient volatile Set
                    
                      KeySet; private transient volatile Set
                     
                       > EntrySet; private transient volatile Collection
                      
                        Values;/*** return the Set view containing the map * Get the Iterator object through the Set view and iterate over the map */public Set
                       
                         > EntrySet () {if (entrySet = null) entrySet = Collections. synchronizedSet (new EntrySet (), this); return entrySet;} // Set View class private class EntrySet extends actset
                        
                          > {Public Iterator
                         
                           > Iterator () {return getIterator (ENTRIES);} public boolean add (Map. Entry
                          
                            O) {return super. add (o);} public boolean contains (Object o) {if (! (O instanceof Map. Entry) return false; Map. Entry
                           Entry = (Map. Entry
                           ) O; Object key = entry. getKey (); Entry
                           [] Tab = table; int hash = key. hashCode (); int index = (hash & 0x7fffff) % tab. length; for (Entry
                           E = tab [index]; e! = Null; e = e. next) if (e. hash = hash & e. equals (entry) return true; return false;} public boolean remove (Object o) {if (! (O instanceof Map. Entry) return false; Map. Entry
                           Entry = (Map. Entry
                           ) O; Object key = entry. getKey (); Entry
                           [] Tab = table; int hash = key. hashCode (); int index = (hash & 0x7FFFFFFF) % tab. length; @ SuppressWarnings ("unchecked") Entry
                           
                             E = (Entry
                            
                              ) Tab [index]; for (Entry
                             
                               Prev = null; e! = Null; prev = e, e = e. next) {if (e. hash = hash & e. equals (entry) {modCount ++; if (prev! = Null) prev. next = e. next; else tab [index] = e. next; count --; e. value = null; return true;} return false;} public int size () {return count;} public void clear () {Hashtable. this. clear () ;}/ *** Returns a {@ link Collection} view of the values contained in this map. * The collection is backed by the map, so changes to the map are * reflected in the collection, and vice-versa. if the map is * modified while an iteration over the collection is in progress * (could t through the iterator's own
                              RemoveOperation), * the results of the iteration are undefined. The collection * supports element removal, which removes the corresponding * mapping from the map, via
                              Iterator. remove,*
                              Collection. remove,
                              RemoveAll,*
                              RetainAllAnd
                              ClearOperations. It does not * support
                              AddOr
                              AddAllOperations. ** @ since 1.2 */public Collection
                              
                                Values () {if (values = null) values = Collections. synchronizedCollection (new ValueCollection (), this); return values;} private class ValueCollection extends AbstractCollection
                               
                                 {Public Iterator
                                
                                  Iterator () {return getIterator (VALUES);} public int size () {return count;} public boolean contains (Object o) {return containsValue (o );} public void clear () {Hashtable. this. clear () ;}// Comparison and hashing/*** implement equals * judgment and so on */public synchronized boolean equals (Object o) {if (o = this) return true; if (! (O instanceof Map) return false; Map
                                 T = (Map
                                 ) O; if (t. size ()! = Size () return false; try {Iterator
                                 
                                   > I = entrySet (). iterator (); while (I. hasNext () {Map. Entry
                                  
                                    E = I. next (); K key = e. getKey (); V value = e. getValue (); if (value = null) {if (! (T. get (key) = null & t. containsKey (key) return false;} else {if (! Value. equals (t. get (key) return false ;}} catch (ClassCastException unused) {return false;} catch (NullPointerException unused) {return false;} return true ;} /*** implement hashCode */public synchronized int hashCode () {/** This code detects the recursion caused by computing the hash code * of a self-referential hash table and prevents the stack overflow * that wowould otherwise result. this allows certain 1.1-era * applets with self-referential hash tables to work. this code * abuses the loadFactor field to do double-duty as a hashCode * in progress flag, so as not to worsen the space performance. * A negative load factor indicates that hash code computation is * in progress. */int h = 0; if (count = 0 | loadFactor <0) return h; // Returns zero loadFactor =-loadFactor; // Mark hashCode computation in progress Entry
                                   [] Tab = table; for (Entry
                                   Entry: tab) {while (entry! = Null) {h + = entry. hashCode (); entry = entry. next ;}} loadFactor =-loadFactor; // Mark hashCode computation complete return h;} @ Overridepublic synchronized boolean replace (K key, V oldValue, V newValue) {Objects. requireNonNull (oldValue); Objects. requireNonNull (newValue); Entry
                                   Tab [] = table; int hash = key. hashCode (); int index = (hash & 0x7FFFFFFF) % tab. length; @ SuppressWarnings ("unchecked") Entry
                                   
                                     E = (Entry
                                    
                                      ) Tab [index]; for (; e! = Null; e = e. next) {if (e. hash = hash) & e. key. equals (key) {if (e. value. equals (oldValue) {e. value = newValue; return true;} else {return false ;}} return false;}/** replace */@ Overridepublic synchronized V replace (K key, V value) {Objects. requireNonNull (value); Entry
                                     Tab [] = table; int hash = key. hashCode (); int index = (hash & 0x7FFFFFFF) % tab. length; @ SuppressWarnings ("unchecked") Entry
                                     
                                       E = (Entry
                                      
                                        ) Tab [index]; for (; e! = Null; e = e. next) {if (e. hash = hash) & e. key. equals (key) {V oldValue = e. value; e. value = value; return oldValue;} return null ;}
                                      
                                     
                                    
                                   
                                  
                                 
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
    
   
  
 

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.