vector与ArrayList、hashmap与hashtable区别

时间:2023-03-09 03:42:20
vector与ArrayList、hashmap与hashtable区别

一、vector与ArrayList区别

    首先要说明的是vector和arraylist都是list的实现类,都是代表链表的数据结构。
    java.util.Vector;  类中
  1.  package java.util;
    publicclassVector<E>
    extendsAbstractList<E>
    implementsList<E>,RandomAccess,Cloneable, java.io.Serializable
    {
    protectedObject[] elementData;
    protectedint elementCount;
    protectedint capacityIncrement;
    privatestaticfinallong serialVersionUID =-2767605614048989439L;
    publicVector(int initialCapacity,int capacityIncrement){
    super();
    if(initialCapacity <0)
    thrownewIllegalArgumentException("Illegal Capacity: "+
    initialCapacity);
    this.elementData =newObject[initialCapacity];
    this.capacityIncrement = capacityIncrement;
    }
    publicVector(int initialCapacity){
    this(initialCapacity,0);
    }
    publicVector(){
    this(10);
    }
    publicVector(Collection<?extends E> c){
    elementData = c.toArray();
    elementCount = elementData.length;
    // c.toArray might (incorrectly) not return Object[] (see 6260652)
    if(elementData.getClass()!=Object[].class)
    elementData =Arrays.copyOf(elementData, elementCount,Object[].class);
    }
    publicsynchronizedvoid copyInto(Object[] anArray){
    System.arraycopy(elementData,0, anArray,0, elementCount);
    }
    /**
    * Trims the capacity of this vector to be the vector's current
    * size. If the capacity of this vector is larger than its current
    * size, then the capacity is changed to equal the size by replacing
    * its internal data array, kept in the field {@code elementData},
    * with a smaller one. An application can use this operation to
    * minimize the storage of a vector.
    */
    publicsynchronizedvoid trimToSize(){
    modCount++;
    int oldCapacity = elementData.length;
    if(elementCount < oldCapacity){
    elementData =Arrays.copyOf(elementData, elementCount);
    }
    }
    publicsynchronizedvoid ensureCapacity(int minCapacity){
    modCount++;
    ensureCapacityHelper(minCapacity);
    }
    /**
    * This implements the unsynchronized semantics of ensureCapacity.
    * Synchronized methods in this class can internally call this
    * method for ensuring capacity without incurring the cost of an
    * extra synchronization.
    *
    * @see #ensureCapacity(int)
    */
    privatevoid ensureCapacityHelper(int minCapacity){
    int oldCapacity = elementData.length;
    if(minCapacity > oldCapacity){
    Object[] oldData = elementData;
    int newCapacity =(capacityIncrement >0)?
    (oldCapacity + capacityIncrement):(oldCapacity *2);
    if(newCapacity < minCapacity){
    newCapacity = minCapacity;
    }
    elementData =Arrays.copyOf(elementData, newCapacity);
    }
    }
    /**
    * Sets the size of this vector. If the new size is greater than the
    * current size, new {@code null} items are added to the end of
    * the vector. If the new size is less than the current size, all
    * components at index {@code newSize} and greater are discarded.
    *
    * @param newSize the new size of this vector
    * @throws ArrayIndexOutOfBoundsException if the new size is negative
    */
    publicsynchronizedvoid setSize(int newSize){
    modCount++;
    if(newSize > elementCount){
    ensureCapacityHelper(newSize);
    }else{
    for(int i = newSize ; i < elementCount ; i++){
    elementData[i]=null;
    }
    }
    elementCount = newSize;
    }
    /**
    * Returns the current capacity of this vector.
    *
    * @return the current capacity (the length of its internal
    * data array, kept in the field {@code elementData}
    * of this vector)
    */
    publicsynchronizedint capacity(){
    return elementData.length;
    }
    /**
    * Returns the number of components in this vector.
    *
    * @return the number of components in this vector
    */
    publicsynchronizedint size(){
    return elementCount;
    }
    /**
    * Tests if this vector has no components.
    *
    * @return {@code true} if and only if this vector has
    * no components, that is, its size is zero;
    * {@code false} otherwise.
    */
    publicsynchronizedboolean isEmpty(){
    return elementCount ==0;
    }
    /**
    * Returns an enumeration of the components of this vector. The
    * returned {@code Enumeration} object will generate all items in
    * this vector. The first item generated is the item at index {@code 0},
    * then the item at index {@code 1}, and so on.
    *
    * @return an enumeration of the components of this vector
    * @see Iterator
    */
    publicEnumeration<E> elements(){
    returnnewEnumeration<E>(){
    int count =0;
    publicboolean hasMoreElements(){
    return count < elementCount;
    }
    public E nextElement(){
    synchronized(Vector.this){
    if(count < elementCount){
    return(E)elementData[count++];
    }
    }
    thrownewNoSuchElementException("Vector Enumeration");
    }
    };
    }
    /**
    * Returns {@code true} if this vector contains the specified element.
    * More formally, returns {@code true} if and only if this vector
    * contains at least one element {@code e} such that
    * <tt>(o==null ? e==null : o.equals(e))</tt>.
    *
    * @param o element whose presence in this vector is to be tested
    * @return {@code true} if this vector contains the specified element
    */
    publicboolean contains(Object o){
    return indexOf(o,0)>=0;
    }
    /**
    * Returns the index of the first occurrence of the specified element
    * in this vector, or -1 if this vector does not contain the element.
    * More formally, returns the lowest index {@code i} such that
    * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
    * or -1 if there is no such index.
    *
    * @param o element to search for
    * @return the index of the first occurrence of the specified element in
    * this vector, or -1 if this vector does not contain the element
    */
    publicint indexOf(Object o){
    return indexOf(o,0);
    }
    /**
    * Returns the index of the first occurrence of the specified element in
    * this vector, searching forwards from {@code index}, or returns -1 if
    * the element is not found.
    * More formally, returns the lowest index {@code i} such that
    * <tt>(i >= index && (o==null ? get(i)==null : o.equals(get(i))))</tt>,
    * or -1 if there is no such index.
    *
    * @param o element to search for
    * @param index index to start searching from
    * @return the index of the first occurrence of the element in
    * this vector at position {@code index} or later in the vector;
    * {@code -1} if the element is not found.
    * @throws IndexOutOfBoundsException if the specified index is negative
    * @see Object#equals(Object)
    */
    publicsynchronizedint indexOf(Object o,int index){
    if(o ==null){
    for(int i = index ; i < elementCount ; i++)
    if(elementData[i]==null)
    return i;
    }else{
    for(int i = index ; i < elementCount ; i++)
    if(o.equals(elementData[i]))
    return i;
    }
    return-1;
    }
    /**
    * Returns the index of the last occurrence of the specified element
    * in this vector, or -1 if this vector does not contain the element.
    * More formally, returns the highest index {@code i} such that
    * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
    * or -1 if there is no such index.
    *
    * @param o element to search for
    * @return the index of the last occurrence of the specified element in
    * this vector, or -1 if this vector does not contain the element
    */
    publicsynchronizedint lastIndexOf(Object o){
    return lastIndexOf(o, elementCount-1);
    }
    /**
    * Returns the index of the last occurrence of the specified element in
    * this vector, searching backwards from {@code index}, or returns -1 if
    * the element is not found.
    * More formally, returns the highest index {@code i} such that
    * <tt>(i <= index && (o==null ? get(i)==null : o.equals(get(i))))</tt>,
    * or -1 if there is no such index.
    *
    * @param o element to search for
    * @param index index to start searching backwards from
    * @return the index of the last occurrence of the element at position
    * less than or equal to {@code index} in this vector;
    * -1 if the element is not found.
    * @throws IndexOutOfBoundsException if the specified index is greater
    * than or equal to the current size of this vector
    */
    publicsynchronizedint lastIndexOf(Object o,int index){
    if(index >= elementCount)
    thrownewIndexOutOfBoundsException(index +" >= "+ elementCount);
    if(o ==null){
    for(int i = index; i >=0; i--)
    if(elementData[i]==null)
    return i;
    }else{
    for(int i = index; i >=0; i--)
    if(o.equals(elementData[i]))
    return i;
    }
    return-1;
    }
    /**
    * Returns the component at the specified index.
    *
    * <p>This method is identical in functionality to the {@link #get(int)}
    * method (which is part of the {@link List} interface).
    *
    * @param index an index into this vector
    * @return the component at the specified index
    * @throws ArrayIndexOutOfBoundsException if the index is out of range
    * ({@code index < 0 || index >= size()})
    */
    publicsynchronized E elementAt(int index){
    if(index >= elementCount){
    thrownewArrayIndexOutOfBoundsException(index +" >= "+ elementCount);
    }
    return(E)elementData[index];
    }
    /**
    * Returns the first component (the item at index {@code 0}) of
    * this vector.
    *
    * @return the first component of this vector
    * @throws NoSuchElementException if this vector has no components
    */
    publicsynchronized E firstElement(){
    if(elementCount ==0){
    thrownewNoSuchElementException();
    }
    return(E)elementData[0];
    }
    /**
    * Returns the last component of the vector.
    *
    * @return the last component of the vector, i.e., the component at index
    * <code>size() - 1</code>.
    * @throws NoSuchElementException if this vector is empty
    */
    publicsynchronized E lastElement(){
    if(elementCount ==0){
    thrownewNoSuchElementException();
    }
    return(E)elementData[elementCount -1];
    }
    /**
    * Sets the component at the specified {@code index} of this
    * vector to be the specified object. The previous component at that
    * position is discarded.
    *
    * <p>The index must be a value greater than or equal to {@code 0}
    * and less than the current size of the vector.
    *
    * <p>This method is identical in functionality to the
    * {@link #set(int, Object) set(int, E)}
    * method (which is part of the {@link List} interface). Note that the
    * {@code set} method reverses the order of the parameters, to more closely
    * match array usage. Note also that the {@code set} method returns the
    * old value that was stored at the specified position.
    *
    * @param obj what the component is to be set to
    * @param index the specified index
    * @throws ArrayIndexOutOfBoundsException if the index is out of range
    * ({@code index < 0 || index >= size()})
    */
    publicsynchronizedvoid setElementAt(E obj,int index){
    if(index >= elementCount){
    thrownewArrayIndexOutOfBoundsException(index +" >= "+
    elementCount);
    }
    elementData[index]= obj;
    }
    publicsynchronizedvoid removeElementAt(int index){
    modCount++;
    if(index >= elementCount){
    thrownewArrayIndexOutOfBoundsException(index +" >= "+
    elementCount);
    }
    elseif(index <0){
    thrownewArrayIndexOutOfBoundsException(index);
    }
    int j = elementCount - index -1;
    if(j >0){
    System.arraycopy(elementData, index +1, elementData, index, j);
    }
    elementCount--;
    elementData[elementCount]=null;/* to let gc do its work */
    }
    /**
    * Inserts the specified object as a component in this vector at the
    * specified {@code index}. Each component in this vector with
    * an index greater or equal to the specified {@code index} is
    * shifted upward to have an index one greater than the value it had
    * previously.
    *
    * <p>The index must be a value greater than or equal to {@code 0}
    * and less than or equal to the current size of the vector. (If the
    * index is equal to the current size of the vector, the new element
    * is appended to the Vector.)
    *
    * <p>This method is identical in functionality to the
    * {@link #add(int, Object) add(int, E)}
    * method (which is part of the {@link List} interface). Note that the
    * {@code add} method reverses the order of the parameters, to more closely
    * match array usage.
    *
    * @param obj the component to insert
    * @param index where to insert the new component
    * @throws ArrayIndexOutOfBoundsException if the index is out of range
    * ({@code index < 0 || index > size()})
    */
    publicsynchronizedvoid insertElementAt(E obj,int index){
    modCount++;
    if(index > elementCount){
    thrownewArrayIndexOutOfBoundsException(index
    +" > "+ elementCount);
    }
    ensureCapacityHelper(elementCount +1);
    System.arraycopy(elementData, index, elementData, index +1, elementCount - index);
    elementData[index]= obj;
    elementCount++;
    }
    /**
    * Adds the specified component to the end of this vector,
    * increasing its size by one. The capacity of this vector is
    * increased if its size becomes greater than its capacity.
    *
    * <p>This method is identical in functionality to the
    * {@link #add(Object) add(E)}
    * method (which is part of the {@link List} interface).
    *
    * @param obj the component to be added
    */
    publicsynchronizedvoid addElement(E obj){
    modCount++;
    ensureCapacityHelper(elementCount +1);
    elementData[elementCount++]= obj;
    }
    /**
    * Removes the first (lowest-indexed) occurrence of the argument
    * from this vector. If the object is found in this vector, each
    * component in the vector with an index greater or equal to the
    * object's index is shifted downward to have an index one smaller
    * than the value it had previously.
    *
    * <p>This method is identical in functionality to the
    * {@link #remove(Object)} method (which is part of the
    * {@link List} interface).
    *
    * @param obj the component to be removed
    * @return {@code true} if the argument was a component of this
    * vector; {@code false} otherwise.
    */
    publicsynchronizedboolean removeElement(Object obj){
    modCount++;
    int i = indexOf(obj);
    if(i >=0){
    removeElementAt(i);
    returntrue;
    }
    returnfalse;
    }
    /**
    * Removes all components from this vector and sets its size to zero.
    *
    * <p>This method is identical in functionality to the {@link #clear}
    * method (which is part of the {@link List} interface).
    */
    publicsynchronizedvoid removeAllElements(){
    modCount++;
    // Let gc do its work
    for(int i =0; i < elementCount; i++)
    elementData[i]=null;
    elementCount =0;
    }
    /**
    * Returns a clone of this vector. The copy will contain a
    * reference to a clone of the internal data array, not a reference
    * to the original internal data array of this {@code Vector} object.
    *
    * @return a clone of this vector
    */
    publicsynchronizedObject clone(){
    try{
    Vector<E> v =(Vector<E>)super.clone();
    v.elementData =Arrays.copyOf(elementData, elementCount);
    v.modCount =0;
    return v;
    }catch(CloneNotSupportedException e){
    // this shouldn't happen, since we are Cloneable
    thrownewInternalError();
    }
    }
    /**
    * Returns an array containing all of the elements in this Vector
    * in the correct order.
    *
    * @since 1.2
    */
    publicsynchronizedObject[] toArray(){
    returnArrays.copyOf(elementData, elementCount);
    }
    publicsynchronized<T> T[] toArray(T[] a){
    if(a.length < elementCount)
    return(T[])Arrays.copyOf(elementData, elementCount, a.getClass());
    System.arraycopy(elementData,0, a,0, elementCount);
    if(a.length > elementCount)
    a[elementCount]=null;
    return a;
    }
    // Positional Access Operations
    /**
    * Returns the element at the specified position in this Vector.
    *
    * @param index index of the element to return
    * @return object at the specified index
    * @throws ArrayIndexOutOfBoundsException if the index is out of range
    * ({@code index < 0 || index >= size()})
    * @since 1.2
    */
    publicsynchronized E get(int index){
    if(index >= elementCount)
    thrownewArrayIndexOutOfBoundsException(index);
    return(E)elementData[index];
    }
    /**
    * Replaces the element at the specified position in this Vector with the
    * specified element.
    *
    * @param index index of the element to replace
    * @param element element to be stored at the specified position
    * @return the element previously at the specified position
    * @throws ArrayIndexOutOfBoundsException if the index is out of range
    * ({@code index < 0 || index >= size()})
    * @since 1.2
    */
    publicsynchronized E set(int index, E element){
    if(index >= elementCount)
    thrownewArrayIndexOutOfBoundsException(index);
    Object oldValue = elementData[index];
    elementData[index]= element;
    return(E)oldValue;
    }
    /**
    * Appends the specified element to the end of this Vector.
    *
    * @param e element to be appended to this Vector
    * @return {@code true} (as specified by {@link Collection#add})
    * @since 1.2
    */
    publicsynchronizedboolean add(E e){
    modCount++;
    ensureCapacityHelper(elementCount +1);
    elementData[elementCount++]= e;
    returntrue;
    }
    publicboolean remove(Object o){
    return removeElement(o);
    }
    publicvoid add(int index, E element){
    insertElementAt(element, index);
    }
    publicsynchronized E remove(int index){
    modCount++;
    if(index >= elementCount)
    thrownewArrayIndexOutOfBoundsException(index);
    Object oldValue = elementData[index];
    int numMoved = elementCount - index -1;
    if(numMoved >0)
    System.arraycopy(elementData, index+1, elementData, index,
    numMoved);
    elementData[--elementCount]=null;// Let gc do its work
    return(E)oldValue;
    }
    publicvoid clear(){
    removeAllElements();
    }
    // Bulk Operations
    publicsynchronizedboolean containsAll(Collection<?> c){
    returnsuper.containsAll(c);
    }
    publicsynchronizedboolean addAll(Collection<?extends E> c){
    modCount++;
    Object[] a = c.toArray();
    int numNew = a.length;
    ensureCapacityHelper(elementCount + numNew);
    System.arraycopy(a,0, elementData, elementCount, numNew);
    elementCount += numNew;
    return numNew !=0;
    }
    publicsynchronizedboolean removeAll(Collection<?> c){
    returnsuper.removeAll(c);
    }
    publicsynchronizedboolean retainAll(Collection<?> c){
    returnsuper.retainAll(c);
    }
    publicsynchronizedboolean addAll(int index,Collection<?extends E> c){
    modCount++;
    if(index <0|| index > elementCount)
    thrownewArrayIndexOutOfBoundsException(index);
    Object[] a = c.toArray();
    int numNew = a.length;
    ensureCapacityHelper(elementCount + numNew);
    int numMoved = elementCount - index;
    if(numMoved >0)
    System.arraycopy(elementData, index, elementData, index + numNew,
    numMoved);
    System.arraycopy(a,0, elementData, index, numNew);
    elementCount += numNew;
    return numNew !=0;
    }
    /**
    * Compares the specified Object with this Vector for equality. Returns
    * true if and only if the specified Object is also a List, both Lists
    * have the same size, and all corresponding pairs of elements in the two
    * Lists are <em>equal</em>. (Two elements {@code e1} and
    * {@code e2} are <em>equal</em> if {@code (e1==null ? e2==null :
    * e1.equals(e2))}.) In other words, two Lists are defined to be
    * equal if they contain the same elements in the same order.
    *
    * @param o the Object to be compared for equality with this Vector
    * @return true if the specified Object is equal to this Vector
    */
    publicsynchronizedboolean equals(Object o){
    returnsuper.equals(o);
    }
    /**
    * Returns the hash code value for this Vector.
    */
    publicsynchronizedint hashCode(){
    returnsuper.hashCode();
    }
    /**
    * Returns a string representation of this Vector, containing
    * the String representation of each element.
    */
    publicsynchronizedString toString(){
    returnsuper.toString();
    }
    publicsynchronizedList<E> subList(int fromIndex,int toIndex){
    returnCollections.synchronizedList(super.subList(fromIndex, toIndex),
    this);
    }
    protectedsynchronizedvoid removeRange(int fromIndex,int toIndex){
    modCount++;
    int numMoved = elementCount - toIndex;
    System.arraycopy(elementData, toIndex, elementData, fromIndex,
    numMoved);
    // Let gc do its work
    int newElementCount = elementCount -(toIndex-fromIndex);
    while(elementCount != newElementCount)
    elementData[--elementCount]=null;
    }
    privatesynchronizedvoid writeObject(java.io.ObjectOutputStream s)
    throws java.io.IOException
    {
    s.defaultWriteObject();
    }
    }
    说明:vector中使用到了synchronized关键字,也就是说vector是线程安全的!同理可知ArrayList是线程不安全的;
                所以vector中操作成员的方法必须保证同步才行,所以效率上就没有ArrayList的高;
                一般情况下,需要保持同步的情况下才使用vector,多数情况下使用ArrayList。
二、hashmap与hashtable
    同vector与arrayList一样,hashmap与hashtable也是相同的道理
看看HashMap的类
     package java.util;
import java.io.*;
publicclassHashMap<K,V>
extendsAbstractMap<K,V>
implementsMap<K,V>,Cloneable,Serializable
{
/**
* The default initial capacity - MUST be a power of two.
*/
staticfinalint DEFAULT_INITIAL_CAPACITY =16;
/**
* The maximum capacity, used if a higher value is implicitly specified
* by either of the constructors with arguments.
* MUST be a power of two <= 1<<30.
*/
staticfinalint MAXIMUM_CAPACITY =1<<30;
/**
* The load factor used when none specified in constructor.
*/
staticfinalfloat DEFAULT_LOAD_FACTOR =0.75f;
/**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
transientEntry[] table;
/**
* The number of key-value mappings contained in this map.
*/
transientint size;
/**
* The next size value at which to resize (capacity * load factor).
* @serial
*/
int threshold;
/**
* The load factor for the hash table.
*
* @serial
*/
finalfloat loadFactor;
/**
* The number of times this HashMap has been structurally modified
* Structural modifications are those that change the number of mappings in
* the HashMap or otherwise modify its internal structure (e.g.,
* rehash). This field is used to make iterators on Collection-views of
* the HashMap fail-fast. (See ConcurrentModificationException).
*/
transientvolatileint modCount;
/**
* Constructs an empty <tt>HashMap</tt> with the specified initial
* capacity and load factor.
*
* @param initialCapacity the initial capacity
* @param loadFactor the load factor
* @throws IllegalArgumentException if the initial capacity is negative
* or the load factor is nonpositive
*/
publicHashMap(int initialCapacity,float loadFactor){
if(initialCapacity <0)
thrownewIllegalArgumentException("Illegal initial capacity: "+
initialCapacity);
if(initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if(loadFactor <=0||Float.isNaN(loadFactor))
thrownewIllegalArgumentException("Illegal load factor: "+
loadFactor);
// Find a power of 2 >= initialCapacity
int capacity =1;
while(capacity < initialCapacity)
capacity <<=1;
this.loadFactor = loadFactor;
threshold =(int)(capacity * loadFactor);
table =newEntry[capacity];
init();
}
/**
* Constructs an empty <tt>HashMap</tt> with the specified initial
* capacity and the default load factor (0.75).
*
* @param initialCapacity the initial capacity.
* @throws IllegalArgumentException if the initial capacity is negative.
*/
publicHashMap(int initialCapacity){
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
/**
* Constructs an empty <tt>HashMap</tt> with the default initial capacity
* (16) and the default load factor (0.75).
*/
publicHashMap(){
this.loadFactor = DEFAULT_LOAD_FACTOR;
threshold =(int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
table =newEntry[DEFAULT_INITIAL_CAPACITY];
init();
}
/**
* Constructs a new <tt>HashMap</tt> with the same mappings as the
* specified <tt>Map</tt>. The <tt>HashMap</tt> is created with
* default load factor (0.75) and an initial capacity sufficient to
* hold the mappings in the specified <tt>Map</tt>.
*
* @param m the map whose mappings are to be placed in this map
* @throws NullPointerException if the specified map is null
*/
publicHashMap(Map<?extends K,?extends V> m){
this(Math.max((int)(m.size()/ DEFAULT_LOAD_FACTOR)+1,
DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
putAllForCreate(m);
}
// internal utilities
/**
* Initialization hook for subclasses. This method is called
* in all constructors and pseudo-constructors (clone, readObject)
* after HashMap has been initialized but before any entries have
* been inserted. (In the absence of this method, readObject would
* require explicit knowledge of subclasses.)
*/
void init(){
}
/**
* Applies a supplemental hash function to a given hashCode, which
* defends against poor quality hash functions. This is critical
* because HashMap uses power-of-two length hash tables, that
* otherwise encounter collisions for hashCodes that do not differ
* in lower bits. Note: Null keys always map to hash 0, thus index 0.
*/
staticint hash(int h){
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^=(h >>>20)^(h >>>12);
return h ^(h >>>7)^(h >>>4);
}
/**
* Returns index for hash code h.
*/
staticint indexFor(int h,int length){
return h &(length-1);
}
/**
* Returns the number of key-value mappings in this map.
*
* @return the number of key-value mappings in this map
*/
publicint size(){
return size;
}
/**
* Returns <tt>true</tt> if this map contains no key-value mappings.
*
* @return <tt>true</tt> if this map contains no key-value mappings
*/
publicboolean isEmpty(){
return size ==0;
}
/**
* Returns the value to which the specified key is mapped,
* or {@code null} if this map contains no mapping for the key.
*
* <p>More formally, if this map contains a mapping from a key
* {@code k} to a value {@code v} such that {@code (key==null ? k==null :
* key.equals(k))}, then this method returns {@code v}; otherwise
* it returns {@code null}. (There can be at most one such mapping.)
*
* <p>A return value of {@code null} does not <i>necessarily</i>
* indicate that the map contains no mapping for the key; it's also
* possible that the map explicitly maps the key to {@code null}.
* The {@link #containsKey containsKey} operation may be used to
* distinguish these two cases.
*
* @see #put(Object, Object)
*/
public V get(Object key){
if(key ==null)
return getForNullKey();
int hash = hash(key.hashCode());
for(Entry<K,V> e = table[indexFor(hash, table.length)];
e !=null;
e = e.next){
Object k;
if(e.hash == hash &&((k = e.key)== key || key.equals(k)))
return e.value;
}
returnnull;
}
/**
* Offloaded version of get() to look up null keys. Null keys map
* to index 0. This null case is split out into separate methods
* for the sake of performance in the two most commonly used
* operations (get and put), but incorporated with conditionals in
* others.
*/
private V getForNullKey(){
for(Entry<K,V> e = table[0]; e !=null; e = e.next){
if(e.key ==null)
return e.value;
}
returnnull;
}
/**
* Returns <tt>true</tt> if this map contains a mapping for the
* specified key.
*
* @param key The key whose presence in this map is to be tested
* @return <tt>true</tt> if this map contains a mapping for the specified
* key.
*/
publicboolean containsKey(Object key){
return getEntry(key)!=null;
}
/**
* Returns the entry associated with the specified key in the
* HashMap. Returns null if the HashMap contains no mapping
* for the key.
*/
finalEntry<K,V> getEntry(Object key){
int hash =(key ==null)?0: hash(key.hashCode());
for(Entry<K,V> e = table[indexFor(hash, table.length)];
e !=null;
e = e.next){
Object k;
if(e.hash == hash &&
((k = e.key)== key ||(key !=null&& key.equals(k))))
return e;
}
returnnull;
}
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
* value is replaced.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
* (A <tt>null</tt> return can also indicate that the map
* previously associated <tt>null</tt> with <tt>key</tt>.)
*/
public V put(K key, V value){
if(key ==null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for(Entry<K,V> e = table[i]; e !=null; e = e.next){
Object k;
if(e.hash == hash &&((k = e.key)== key || key.equals(k))){
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
returnnull;
}
/**
* Offloaded version of put for null keys
*/
private V putForNullKey(V value){
for(Entry<K,V> e = table[0]; e !=null; e = e.next){
if(e.key ==null){
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(0,null, value,0);
returnnull;
}
// These methods are used when serializing HashSets
int capacity(){return table.length;}
float loadFactor(){return loadFactor;}
} HashTable类 publicclassHashtable<K,V>
extendsDictionary<K,V>
implementsMap<K,V>,Cloneable, java.io.Serializable{
/**
* The hash table data.
*/
privatetransientEntry[] table;
/**
* The total number of entries in the hash table.
*/
privatetransientint count;
/**
* The table is rehashed when its size exceeds this threshold. (The
* value of this field is (int)(capacity * loadFactor).)
*
* @serial
*/
privateint threshold;
/**
* The load factor for the hashtable.
*
* @serial
*/
privatefloat loadFactor;
/**
* The number of times this Hashtable has been structurally modified
* Structural modifications are those that change the number of entries in
* the Hashtable or otherwise modify its internal structure (e.g.,
* rehash). This field is used to make iterators on Collection-views of
* the Hashtable fail-fast. (See ConcurrentModificationException).
*/
privatetransientint modCount =0;
/** use serialVersionUID from JDK 1.0.2 for interoperability */
privatestaticfinallong serialVersionUID =1421746759512286392L;
/**
* Constructs a new, empty hashtable with the specified initial
* capacity and the specified load factor.
*
* @param initialCapacity the initial capacity of the hashtable.
* @param loadFactor the load factor of the hashtable.
* @exception IllegalArgumentException if the initial capacity is less
* than zero, or if the load factor is nonpositive.
*/
publicHashtable(int initialCapacity,float loadFactor){
if(initialCapacity <0)
thrownewIllegalArgumentException("Illegal Capacity: "+
initialCapacity);
if(loadFactor <=0||Float.isNaN(loadFactor))
thrownewIllegalArgumentException("Illegal Load: "+loadFactor);
if(initialCapacity==0)
initialCapacity =1;
this.loadFactor = loadFactor;
table =newEntry[initialCapacity];
threshold =(int)(initialCapacity * loadFactor);
}
/**
* Constructs a new, empty hashtable with the specified initial capacity
* and default load factor (0.75).
*
* @param initialCapacity the initial capacity of the hashtable.
* @exception IllegalArgumentException if the initial capacity is less
* than zero.
*/
publicHashtable(int initialCapacity){
this(initialCapacity,0.75f);
}
/**
* Constructs a new, empty hashtable with a default initial capacity (11)
* and load factor (0.75).
*/
publicHashtable(){
this(11,0.75f);
}
/**
* Constructs a new hashtable with the same mappings as the given
* Map. The hashtable is created with an initial capacity sufficient to
* hold the mappings in the given Map and a default load factor (0.75).
*
* @param t the map whose mappings are to be placed in this map.
* @throws NullPointerException if the specified map is null.
* @since 1.2
*/
publicHashtable(Map<?extends K,?extends V> t){
this(Math.max(2*t.size(),11),0.75f);
putAll(t);
}
/**
* Returns the number of keys in this hashtable.
*
* @return the number of keys in this hashtable.
*/
publicsynchronizedint size(){
return count;
}
/**
* Tests if this hashtable maps no keys to values.
*
* @return <code>true</code> if this hashtable maps no keys to values;
* <code>false</code> otherwise.
*/
publicsynchronizedboolean isEmpty(){
return count ==0;
}
/**
* Returns an enumeration of the keys in this hashtable.
*
* @return an enumeration of the keys in this hashtable.
* @see Enumeration
* @see #elements()
* @see #keySet()
* @see Map
*/
publicsynchronizedEnumeration<K> keys(){
returnthis.<K>getEnumeration(KEYS);
}
  1.     HashTable的方法是同步的,HashMap不能同步,所以在线程多的场合要使用HashTable;
  2. HashTable不允许空值(key和value都不可以为null),hashmap则可以为null
  3. HashTable有一个contains()的方法,功能和containsValue()一样
  4. HashTable使用Enumeration,而HashMap使用Iterator
  5. HashTabe中的hash数组默认大小为11,增长方式为old*2+1,hashmap的hash为16,是2的指数倍
  6. 哈希值的使用不同,HashTable直接使用对象hashcode,而HashMap会重新计算hash值