一、vector与ArrayList区别
首先要说明的是vector和arraylist都是list的实现类,都是代表链表的数据结构。
java.util.Vector; 类中
-
1 package java.util; 2 publicclassVector<E> 3 extendsAbstractList<E> 4 implementsList<E>,RandomAccess,Cloneable, java.io.Serializable 5 { 6 protectedObject[] elementData; 7 protectedint elementCount; 8 protectedint capacityIncrement; 9 privatestaticfinallong serialVersionUID =-2767605614048989439L; 10 publicVector(int initialCapacity,int capacityIncrement){ 11 super(); 12 if(initialCapacity <0) 13 thrownewIllegalArgumentException("Illegal Capacity: "+ 14 initialCapacity); 15 this.elementData =newObject[initialCapacity]; 16 this.capacityIncrement = capacityIncrement; 17 } 18 publicVector(int initialCapacity){ 19 this(initialCapacity,0); 20 } 21 publicVector(){ 22 this(10); 23 } 24 publicVector(Collection<?extends E> c){ 25 elementData = c.toArray(); 26 elementCount = elementData.length; 27 // c.toArray might (incorrectly) not return Object[] (see 6260652) 28 if(elementData.getClass()!=Object[].class) 29 elementData =Arrays.copyOf(elementData, elementCount,Object[].class); 30 } 31 publicsynchronizedvoid copyInto(Object[] anArray){ 32 System.arraycopy(elementData,0, anArray,0, elementCount); 33 } 34 /** 35 * Trims the capacity of this vector to be the vector's current 36 * size. If the capacity of this vector is larger than its current 37 * size, then the capacity is changed to equal the size by replacing 38 * its internal data array, kept in the field {@code elementData}, 39 * with a smaller one. An application can use this operation to 40 * minimize the storage of a vector. 41 */ 42 publicsynchronizedvoid trimToSize(){ 43 modCount++; 44 int oldCapacity = elementData.length; 45 if(elementCount < oldCapacity){ 46 elementData =Arrays.copyOf(elementData, elementCount); 47 } 48 } 49 publicsynchronizedvoid ensureCapacity(int minCapacity){ 50 modCount++; 51 ensureCapacityHelper(minCapacity); 52 } 53 /** 54 * This implements the unsynchronized semantics of ensureCapacity. 55 * Synchronized methods in this class can internally call this 56 * method for ensuring capacity without incurring the cost of an 57 * extra synchronization. 58 * 59 * @see #ensureCapacity(int) 60 */ 61 privatevoid ensureCapacityHelper(int minCapacity){ 62 int oldCapacity = elementData.length; 63 if(minCapacity > oldCapacity){ 64 Object[] oldData = elementData; 65 int newCapacity =(capacityIncrement >0)? 66 (oldCapacity + capacityIncrement):(oldCapacity *2); 67 if(newCapacity < minCapacity){ 68 newCapacity = minCapacity; 69 } 70 elementData =Arrays.copyOf(elementData, newCapacity); 71 } 72 } 73 /** 74 * Sets the size of this vector. If the new size is greater than the 75 * current size, new {@code null} items are added to the end of 76 * the vector. If the new size is less than the current size, all 77 * components at index {@code newSize} and greater are discarded. 78 * 79 * @param newSize the new size of this vector 80 * @throws ArrayIndexOutOfBoundsException if the new size is negative 81 */ 82 publicsynchronizedvoid setSize(int newSize){ 83 modCount++; 84 if(newSize > elementCount){ 85 ensureCapacityHelper(newSize); 86 }else{ 87 for(int i = newSize ; i < elementCount ; i++){ 88 elementData[i]=null; 89 } 90 } 91 elementCount = newSize; 92 } 93 /** 94 * Returns the current capacity of this vector. 95 * 96 * @return the current capacity (the length of its internal 97 * data array, kept in the field {@code elementData} 98 * of this vector) 99 */ 100 publicsynchronizedint capacity(){ 101 return elementData.length; 102 } 103 /** 104 * Returns the number of components in this vector. 105 * 106 * @return the number of components in this vector 107 */ 108 publicsynchronizedint size(){ 109 return elementCount; 110 } 111 /** 112 * Tests if this vector has no components. 113 * 114 * @return {@code true} if and only if this vector has 115 * no components, that is, its size is zero; 116 * {@code false} otherwise. 117 */ 118 publicsynchronizedboolean isEmpty(){ 119 return elementCount ==0; 120 } 121 /** 122 * Returns an enumeration of the components of this vector. The 123 * returned {@code Enumeration} object will generate all items in 124 * this vector. The first item generated is the item at index {@code 0}, 125 * then the item at index {@code 1}, and so on. 126 * 127 * @return an enumeration of the components of this vector 128 * @see Iterator 129 */ 130 publicEnumeration<E> elements(){ 131 returnnewEnumeration<E>(){ 132 int count =0; 133 publicboolean hasMoreElements(){ 134 return count < elementCount; 135 } 136 public E nextElement(){ 137 synchronized(Vector.this){ 138 if(count < elementCount){ 139 return(E)elementData[count++]; 140 } 141 } 142 thrownewNoSuchElementException("Vector Enumeration"); 143 } 144 }; 145 } 146 /** 147 * Returns {@code true} if this vector contains the specified element. 148 * More formally, returns {@code true} if and only if this vector 149 * contains at least one element {@code e} such that 150 * <tt>(o==null ? e==null : o.equals(e))</tt>. 151 * 152 * @param o element whose presence in this vector is to be tested 153 * @return {@code true} if this vector contains the specified element 154 */ 155 publicboolean contains(Object o){ 156 return indexOf(o,0)>=0; 157 } 158 /** 159 * Returns the index of the first occurrence of the specified element 160 * in this vector, or -1 if this vector does not contain the element. 161 * More formally, returns the lowest index {@code i} such that 162 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, 163 * or -1 if there is no such index. 164 * 165 * @param o element to search for 166 * @return the index of the first occurrence of the specified element in 167 * this vector, or -1 if this vector does not contain the element 168 */ 169 publicint indexOf(Object o){ 170 return indexOf(o,0); 171 } 172 /** 173 * Returns the index of the first occurrence of the specified element in 174 * this vector, searching forwards from {@code index}, or returns -1 if 175 * the element is not found. 176 * More formally, returns the lowest index {@code i} such that 177 * <tt>(i >= index && (o==null ? get(i)==null : o.equals(get(i))))</tt>, 178 * or -1 if there is no such index. 179 * 180 * @param o element to search for 181 * @param index index to start searching from 182 * @return the index of the first occurrence of the element in 183 * this vector at position {@code index} or later in the vector; 184 * {@code -1} if the element is not found. 185 * @throws IndexOutOfBoundsException if the specified index is negative 186 * @see Object#equals(Object) 187 */ 188 publicsynchronizedint indexOf(Object o,int index){ 189 if(o ==null){ 190 for(int i = index ; i < elementCount ; i++) 191 if(elementData[i]==null) 192 return i; 193 }else{ 194 for(int i = index ; i < elementCount ; i++) 195 if(o.equals(elementData[i])) 196 return i; 197 } 198 return-1; 199 } 200 /** 201 * Returns the index of the last occurrence of the specified element 202 * in this vector, or -1 if this vector does not contain the element. 203 * More formally, returns the highest index {@code i} such that 204 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, 205 * or -1 if there is no such index. 206 * 207 * @param o element to search for 208 * @return the index of the last occurrence of the specified element in 209 * this vector, or -1 if this vector does not contain the element 210 */ 211 publicsynchronizedint lastIndexOf(Object o){ 212 return lastIndexOf(o, elementCount-1); 213 } 214 /** 215 * Returns the index of the last occurrence of the specified element in 216 * this vector, searching backwards from {@code index}, or returns -1 if 217 * the element is not found. 218 * More formally, returns the highest index {@code i} such that 219 * <tt>(i <= index && (o==null ? get(i)==null : o.equals(get(i))))</tt>, 220 * or -1 if there is no such index. 221 * 222 * @param o element to search for 223 * @param index index to start searching backwards from 224 * @return the index of the last occurrence of the element at position 225 * less than or equal to {@code index} in this vector; 226 * -1 if the element is not found. 227 * @throws IndexOutOfBoundsException if the specified index is greater 228 * than or equal to the current size of this vector 229 */ 230 publicsynchronizedint lastIndexOf(Object o,int index){ 231 if(index >= elementCount) 232 thrownewIndexOutOfBoundsException(index +" >= "+ elementCount); 233 if(o ==null){ 234 for(int i = index; i >=0; i--) 235 if(elementData[i]==null) 236 return i; 237 }else{ 238 for(int i = index; i >=0; i--) 239 if(o.equals(elementData[i])) 240 return i; 241 } 242 return-1; 243 } 244 /** 245 * Returns the component at the specified index. 246 * 247 * <p>This method is identical in functionality to the {@link #get(int)} 248 * method (which is part of the {@link List} interface). 249 * 250 * @param index an index into this vector 251 * @return the component at the specified index 252 * @throws ArrayIndexOutOfBoundsException if the index is out of range 253 * ({@code index < 0 || index >= size()}) 254 */ 255 publicsynchronized E elementAt(int index){ 256 if(index >= elementCount){ 257 thrownewArrayIndexOutOfBoundsException(index +" >= "+ elementCount); 258 } 259 return(E)elementData[index]; 260 } 261 /** 262 * Returns the first component (the item at index {@code 0}) of 263 * this vector. 264 * 265 * @return the first component of this vector 266 * @throws NoSuchElementException if this vector has no components 267 */ 268 publicsynchronized E firstElement(){ 269 if(elementCount ==0){ 270 thrownewNoSuchElementException(); 271 } 272 return(E)elementData[0]; 273 } 274 /** 275 * Returns the last component of the vector. 276 * 277 * @return the last component of the vector, i.e., the component at index 278 * <code>size() - 1</code>. 279 * @throws NoSuchElementException if this vector is empty 280 */ 281 publicsynchronized E lastElement(){ 282 if(elementCount ==0){ 283 thrownewNoSuchElementException(); 284 } 285 return(E)elementData[elementCount -1]; 286 } 287 /** 288 * Sets the component at the specified {@code index} of this 289 * vector to be the specified object. The previous component at that 290 * position is discarded. 291 * 292 * <p>The index must be a value greater than or equal to {@code 0} 293 * and less than the current size of the vector. 294 * 295 * <p>This method is identical in functionality to the 296 * {@link #set(int, Object) set(int, E)} 297 * method (which is part of the {@link List} interface). Note that the 298 * {@code set} method reverses the order of the parameters, to more closely 299 * match array usage. Note also that the {@code set} method returns the 300 * old value that was stored at the specified position. 301 * 302 * @param obj what the component is to be set to 303 * @param index the specified index 304 * @throws ArrayIndexOutOfBoundsException if the index is out of range 305 * ({@code index < 0 || index >= size()}) 306 */ 307 publicsynchronizedvoid setElementAt(E obj,int index){ 308 if(index >= elementCount){ 309 thrownewArrayIndexOutOfBoundsException(index +" >= "+ 310 elementCount); 311 } 312 elementData[index]= obj; 313 } 314 publicsynchronizedvoid removeElementAt(int index){ 315 modCount++; 316 if(index >= elementCount){ 317 thrownewArrayIndexOutOfBoundsException(index +" >= "+ 318 elementCount); 319 } 320 elseif(index <0){ 321 thrownewArrayIndexOutOfBoundsException(index); 322 } 323 int j = elementCount - index -1; 324 if(j >0){ 325 System.arraycopy(elementData, index +1, elementData, index, j); 326 } 327 elementCount--; 328 elementData[elementCount]=null;/* to let gc do its work */ 329 } 330 /** 331 * Inserts the specified object as a component in this vector at the 332 * specified {@code index}. Each component in this vector with 333 * an index greater or equal to the specified {@code index} is 334 * shifted upward to have an index one greater than the value it had 335 * previously. 336 * 337 * <p>The index must be a value greater than or equal to {@code 0} 338 * and less than or equal to the current size of the vector. (If the 339 * index is equal to the current size of the vector, the new element 340 * is appended to the Vector.) 341 * 342 * <p>This method is identical in functionality to the 343 * {@link #add(int, Object) add(int, E)} 344 * method (which is part of the {@link List} interface). Note that the 345 * {@code add} method reverses the order of the parameters, to more closely 346 * match array usage. 347 * 348 * @param obj the component to insert 349 * @param index where to insert the new component 350 * @throws ArrayIndexOutOfBoundsException if the index is out of range 351 * ({@code index < 0 || index > size()}) 352 */ 353 publicsynchronizedvoid insertElementAt(E obj,int index){ 354 modCount++; 355 if(index > elementCount){ 356 thrownewArrayIndexOutOfBoundsException(index 357 +" > "+ elementCount); 358 } 359 ensureCapacityHelper(elementCount +1); 360 System.arraycopy(elementData, index, elementData, index +1, elementCount - index); 361 elementData[index]= obj; 362 elementCount++; 363 } 364 /** 365 * Adds the specified component to the end of this vector, 366 * increasing its size by one. The capacity of this vector is 367 * increased if its size becomes greater than its capacity. 368 * 369 * <p>This method is identical in functionality to the 370 * {@link #add(Object) add(E)} 371 * method (which is part of the {@link List} interface). 372 * 373 * @param obj the component to be added 374 */ 375 publicsynchronizedvoid addElement(E obj){ 376 modCount++; 377 ensureCapacityHelper(elementCount +1); 378 elementData[elementCount++]= obj; 379 } 380 /** 381 * Removes the first (lowest-indexed) occurrence of the argument 382 * from this vector. If the object is found in this vector, each 383 * component in the vector with an index greater or equal to the 384 * object's index is shifted downward to have an index one smaller 385 * than the value it had previously. 386 * 387 * <p>This method is identical in functionality to the 388 * {@link #remove(Object)} method (which is part of the 389 * {@link List} interface). 390 * 391 * @param obj the component to be removed 392 * @return {@code true} if the argument was a component of this 393 * vector; {@code false} otherwise. 394 */ 395 publicsynchronizedboolean removeElement(Object obj){ 396 modCount++; 397 int i = indexOf(obj); 398 if(i >=0){ 399 removeElementAt(i); 400 returntrue; 401 } 402 returnfalse; 403 } 404 /** 405 * Removes all components from this vector and sets its size to zero. 406 * 407 * <p>This method is identical in functionality to the {@link #clear} 408 * method (which is part of the {@link List} interface). 409 */ 410 publicsynchronizedvoid removeAllElements(){ 411 modCount++; 412 // Let gc do its work 413 for(int i =0; i < elementCount; i++) 414 elementData[i]=null; 415 elementCount =0; 416 } 417 /** 418 * Returns a clone of this vector. The copy will contain a 419 * reference to a clone of the internal data array, not a reference 420 * to the original internal data array of this {@code Vector} object. 421 * 422 * @return a clone of this vector 423 */ 424 publicsynchronizedObject clone(){ 425 try{ 426 Vector<E> v =(Vector<E>)super.clone(); 427 v.elementData =Arrays.copyOf(elementData, elementCount); 428 v.modCount =0; 429 return v; 430 }catch(CloneNotSupportedException e){ 431 // this shouldn't happen, since we are Cloneable 432 thrownewInternalError(); 433 } 434 } 435 /** 436 * Returns an array containing all of the elements in this Vector 437 * in the correct order. 438 * 439 * @since 1.2 440 */ 441 publicsynchronizedObject[] toArray(){ 442 returnArrays.copyOf(elementData, elementCount); 443 } 444 publicsynchronized<T> T[] toArray(T[] a){ 445 if(a.length < elementCount) 446 return(T[])Arrays.copyOf(elementData, elementCount, a.getClass()); 447 System.arraycopy(elementData,0, a,0, elementCount); 448 if(a.length > elementCount) 449 a[elementCount]=null; 450 return a; 451 } 452 // Positional Access Operations 453 /** 454 * Returns the element at the specified position in this Vector. 455 * 456 * @param index index of the element to return 457 * @return object at the specified index 458 * @throws ArrayIndexOutOfBoundsException if the index is out of range 459 * ({@code index < 0 || index >= size()}) 460 * @since 1.2 461 */ 462 publicsynchronized E get(int index){ 463 if(index >= elementCount) 464 thrownewArrayIndexOutOfBoundsException(index); 465 return(E)elementData[index]; 466 } 467 /** 468 * Replaces the element at the specified position in this Vector with the 469 * specified element. 470 * 471 * @param index index of the element to replace 472 * @param element element to be stored at the specified position 473 * @return the element previously at the specified position 474 * @throws ArrayIndexOutOfBoundsException if the index is out of range 475 * ({@code index < 0 || index >= size()}) 476 * @since 1.2 477 */ 478 publicsynchronized E set(int index, E element){ 479 if(index >= elementCount) 480 thrownewArrayIndexOutOfBoundsException(index); 481 Object oldValue = elementData[index]; 482 elementData[index]= element; 483 return(E)oldValue; 484 } 485 /** 486 * Appends the specified element to the end of this Vector. 487 * 488 * @param e element to be appended to this Vector 489 * @return {@code true} (as specified by {@link Collection#add}) 490 * @since 1.2 491 */ 492 publicsynchronizedboolean add(E e){ 493 modCount++; 494 ensureCapacityHelper(elementCount +1); 495 elementData[elementCount++]= e; 496 returntrue; 497 } 498 publicboolean remove(Object o){ 499 return removeElement(o); 500 } 501 publicvoid add(int index, E element){ 502 insertElementAt(element, index); 503 } 504 publicsynchronized E remove(int index){ 505 modCount++; 506 if(index >= elementCount) 507 thrownewArrayIndexOutOfBoundsException(index); 508 Object oldValue = elementData[index]; 509 int numMoved = elementCount - index -1; 510 if(numMoved >0) 511 System.arraycopy(elementData, index+1, elementData, index, 512 numMoved); 513 elementData[--elementCount]=null;// Let gc do its work 514 return(E)oldValue; 515 } 516 publicvoid clear(){ 517 removeAllElements(); 518 } 519 // Bulk Operations 520 publicsynchronizedboolean containsAll(Collection<?> c){ 521 returnsuper.containsAll(c); 522 } 523 publicsynchronizedboolean addAll(Collection<?extends E> c){ 524 modCount++; 525 Object[] a = c.toArray(); 526 int numNew = a.length; 527 ensureCapacityHelper(elementCount + numNew); 528 System.arraycopy(a,0, elementData, elementCount, numNew); 529 elementCount += numNew; 530 return numNew !=0; 531 } 532 publicsynchronizedboolean removeAll(Collection<?> c){ 533 returnsuper.removeAll(c); 534 } 535 publicsynchronizedboolean retainAll(Collection<?> c){ 536 returnsuper.retainAll(c); 537 } 538 publicsynchronizedboolean addAll(int index,Collection<?extends E> c){ 539 modCount++; 540 if(index <0|| index > elementCount) 541 thrownewArrayIndexOutOfBoundsException(index); 542 Object[] a = c.toArray(); 543 int numNew = a.length; 544 ensureCapacityHelper(elementCount + numNew); 545 int numMoved = elementCount - index; 546 if(numMoved >0) 547 System.arraycopy(elementData, index, elementData, index + numNew, 548 numMoved); 549 System.arraycopy(a,0, elementData, index, numNew); 550 elementCount += numNew; 551 return numNew !=0; 552 } 553 /** 554 * Compares the specified Object with this Vector for equality. Returns 555 * true if and only if the specified Object is also a List, both Lists 556 * have the same size, and all corresponding pairs of elements in the two 557 * Lists are <em>equal</em>. (Two elements {@code e1} and 558 * {@code e2} are <em>equal</em> if {@code (e1==null ? e2==null : 559 * e1.equals(e2))}.) In other words, two Lists are defined to be 560 * equal if they contain the same elements in the same order. 561 * 562 * @param o the Object to be compared for equality with this Vector 563 * @return true if the specified Object is equal to this Vector 564 */ 565 publicsynchronizedboolean equals(Object o){ 566 returnsuper.equals(o); 567 } 568 /** 569 * Returns the hash code value for this Vector. 570 */ 571 publicsynchronizedint hashCode(){ 572 returnsuper.hashCode(); 573 } 574 /** 575 * Returns a string representation of this Vector, containing 576 * the String representation of each element. 577 */ 578 publicsynchronizedString toString(){ 579 returnsuper.toString(); 580 } 581 publicsynchronizedList<E> subList(int fromIndex,int toIndex){ 582 returnCollections.synchronizedList(super.subList(fromIndex, toIndex), 583 this); 584 } 585 protectedsynchronizedvoid removeRange(int fromIndex,int toIndex){ 586 modCount++; 587 int numMoved = elementCount - toIndex; 588 System.arraycopy(elementData, toIndex, elementData, fromIndex, 589 numMoved); 590 // Let gc do its work 591 int newElementCount = elementCount -(toIndex-fromIndex); 592 while(elementCount != newElementCount) 593 elementData[--elementCount]=null; 594 } 595 privatesynchronizedvoid writeObject(java.io.ObjectOutputStream s) 596 throws java.io.IOException 597 { 598 s.defaultWriteObject(); 599 } 600 }
说明:vector中使用到了synchronized关键字,也就是说vector是线程安全的!同理可知ArrayList是线程不安全的;
所以vector中操作成员的方法必须保证同步才行,所以效率上就没有ArrayList的高;
一般情况下,需要保持同步的情况下才使用vector,多数情况下使用ArrayList。
二、hashmap与hashtable
同vector与arrayList一样,hashmap与hashtable也是相同的道理
看看HashMap的类
1 package java.util; 2 import java.io.*; 3 publicclassHashMap<K,V> 4 extendsAbstractMap<K,V> 5 implementsMap<K,V>,Cloneable,Serializable 6 { 7 /** 8 * The default initial capacity - MUST be a power of two. 9 */ 10 staticfinalint DEFAULT_INITIAL_CAPACITY =16; 11 /** 12 * The maximum capacity, used if a higher value is implicitly specified 13 * by either of the constructors with arguments. 14 * MUST be a power of two <= 1<<30. 15 */ 16 staticfinalint MAXIMUM_CAPACITY =1<<30; 17 /** 18 * The load factor used when none specified in constructor. 19 */ 20 staticfinalfloat DEFAULT_LOAD_FACTOR =0.75f; 21 /** 22 * The table, resized as necessary. Length MUST Always be a power of two. 23 */ 24 transientEntry[] table; 25 /** 26 * The number of key-value mappings contained in this map. 27 */ 28 transientint size; 29 /** 30 * The next size value at which to resize (capacity * load factor). 31 * @serial 32 */ 33 int threshold; 34 /** 35 * The load factor for the hash table. 36 * 37 * @serial 38 */ 39 finalfloat loadFactor; 40 /** 41 * The number of times this HashMap has been structurally modified 42 * Structural modifications are those that change the number of mappings in 43 * the HashMap or otherwise modify its internal structure (e.g., 44 * rehash). This field is used to make iterators on Collection-views of 45 * the HashMap fail-fast. (See ConcurrentModificationException). 46 */ 47 transientvolatileint modCount; 48 /** 49 * Constructs an empty <tt>HashMap</tt> with the specified initial 50 * capacity and load factor. 51 * 52 * @param initialCapacity the initial capacity 53 * @param loadFactor the load factor 54 * @throws IllegalArgumentException if the initial capacity is negative 55 * or the load factor is nonpositive 56 */ 57 publicHashMap(int initialCapacity,float loadFactor){ 58 if(initialCapacity <0) 59 thrownewIllegalArgumentException("Illegal initial capacity: "+ 60 initialCapacity); 61 if(initialCapacity > MAXIMUM_CAPACITY) 62 initialCapacity = MAXIMUM_CAPACITY; 63 if(loadFactor <=0||Float.isNaN(loadFactor)) 64 thrownewIllegalArgumentException("Illegal load factor: "+ 65 loadFactor); 66 // Find a power of 2 >= initialCapacity 67 int capacity =1; 68 while(capacity < initialCapacity) 69 capacity <<=1; 70 this.loadFactor = loadFactor; 71 threshold =(int)(capacity * loadFactor); 72 table =newEntry[capacity]; 73 init(); 74 } 75 /** 76 * Constructs an empty <tt>HashMap</tt> with the specified initial 77 * capacity and the default load factor (0.75). 78 * 79 * @param initialCapacity the initial capacity. 80 * @throws IllegalArgumentException if the initial capacity is negative. 81 */ 82 publicHashMap(int initialCapacity){ 83 this(initialCapacity, DEFAULT_LOAD_FACTOR); 84 } 85 /** 86 * Constructs an empty <tt>HashMap</tt> with the default initial capacity 87 * (16) and the default load factor (0.75). 88 */ 89 publicHashMap(){ 90 this.loadFactor = DEFAULT_LOAD_FACTOR; 91 threshold =(int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR); 92 table =newEntry[DEFAULT_INITIAL_CAPACITY]; 93 init(); 94 } 95 /** 96 * Constructs a new <tt>HashMap</tt> with the same mappings as the 97 * specified <tt>Map</tt>. The <tt>HashMap</tt> is created with 98 * default load factor (0.75) and an initial capacity sufficient to 99 * hold the mappings in the specified <tt>Map</tt>. 100 * 101 * @param m the map whose mappings are to be placed in this map 102 * @throws NullPointerException if the specified map is null 103 */ 104 publicHashMap(Map<?extends K,?extends V> m){ 105 this(Math.max((int)(m.size()/ DEFAULT_LOAD_FACTOR)+1, 106 DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR); 107 putAllForCreate(m); 108 } 109 // internal utilities 110 /** 111 * Initialization hook for subclasses. This method is called 112 * in all constructors and pseudo-constructors (clone, readObject) 113 * after HashMap has been initialized but before any entries have 114 * been inserted. (In the absence of this method, readObject would 115 * require explicit knowledge of subclasses.) 116 */ 117 void init(){ 118 } 119 /** 120 * Applies a supplemental hash function to a given hashCode, which 121 * defends against poor quality hash functions. This is critical 122 * because HashMap uses power-of-two length hash tables, that 123 * otherwise encounter collisions for hashCodes that do not differ 124 * in lower bits. Note: Null keys always map to hash 0, thus index 0. 125 */ 126 staticint hash(int h){ 127 // This function ensures that hashCodes that differ only by 128 // constant multiples at each bit position have a bounded 129 // number of collisions (approximately 8 at default load factor). 130 h ^=(h >>>20)^(h >>>12); 131 return h ^(h >>>7)^(h >>>4); 132 } 133 /** 134 * Returns index for hash code h. 135 */ 136 staticint indexFor(int h,int length){ 137 return h &(length-1); 138 } 139 /** 140 * Returns the number of key-value mappings in this map. 141 * 142 * @return the number of key-value mappings in this map 143 */ 144 publicint size(){ 145 return size; 146 } 147 /** 148 * Returns <tt>true</tt> if this map contains no key-value mappings. 149 * 150 * @return <tt>true</tt> if this map contains no key-value mappings 151 */ 152 publicboolean isEmpty(){ 153 return size ==0; 154 } 155 /** 156 * Returns the value to which the specified key is mapped, 157 * or {@code null} if this map contains no mapping for the key. 158 * 159 * <p>More formally, if this map contains a mapping from a key 160 * {@code k} to a value {@code v} such that {@code (key==null ? k==null : 161 * key.equals(k))}, then this method returns {@code v}; otherwise 162 * it returns {@code null}. (There can be at most one such mapping.) 163 * 164 * <p>A return value of {@code null} does not <i>necessarily</i> 165 * indicate that the map contains no mapping for the key; it's also 166 * possible that the map explicitly maps the key to {@code null}. 167 * The {@link #containsKey containsKey} operation may be used to 168 * distinguish these two cases. 169 * 170 * @see #put(Object, Object) 171 */ 172 public V get(Object key){ 173 if(key ==null) 174 return getForNullKey(); 175 int hash = hash(key.hashCode()); 176 for(Entry<K,V> e = table[indexFor(hash, table.length)]; 177 e !=null; 178 e = e.next){ 179 Object k; 180 if(e.hash == hash &&((k = e.key)== key || key.equals(k))) 181 return e.value; 182 } 183 returnnull; 184 } 185 /** 186 * Offloaded version of get() to look up null keys. Null keys map 187 * to index 0. This null case is split out into separate methods 188 * for the sake of performance in the two most commonly used 189 * operations (get and put), but incorporated with conditionals in 190 * others. 191 */ 192 private V getForNullKey(){ 193 for(Entry<K,V> e = table[0]; e !=null; e = e.next){ 194 if(e.key ==null) 195 return e.value; 196 } 197 returnnull; 198 } 199 /** 200 * Returns <tt>true</tt> if this map contains a mapping for the 201 * specified key. 202 * 203 * @param key The key whose presence in this map is to be tested 204 * @return <tt>true</tt> if this map contains a mapping for the specified 205 * key. 206 */ 207 publicboolean containsKey(Object key){ 208 return getEntry(key)!=null; 209 } 210 /** 211 * Returns the entry associated with the specified key in the 212 * HashMap. Returns null if the HashMap contains no mapping 213 * for the key. 214 */ 215 finalEntry<K,V> getEntry(Object key){ 216 int hash =(key ==null)?0: hash(key.hashCode()); 217 for(Entry<K,V> e = table[indexFor(hash, table.length)]; 218 e !=null; 219 e = e.next){ 220 Object k; 221 if(e.hash == hash && 222 ((k = e.key)== key ||(key !=null&& key.equals(k)))) 223 return e; 224 } 225 returnnull; 226 } 227 /** 228 * Associates the specified value with the specified key in this map. 229 * If the map previously contained a mapping for the key, the old 230 * value is replaced. 231 * 232 * @param key key with which the specified value is to be associated 233 * @param value value to be associated with the specified key 234 * @return the previous value associated with <tt>key</tt>, or 235 * <tt>null</tt> if there was no mapping for <tt>key</tt>. 236 * (A <tt>null</tt> return can also indicate that the map 237 * previously associated <tt>null</tt> with <tt>key</tt>.) 238 */ 239 public V put(K key, V value){ 240 if(key ==null) 241 return putForNullKey(value); 242 int hash = hash(key.hashCode()); 243 int i = indexFor(hash, table.length); 244 for(Entry<K,V> e = table[i]; e !=null; e = e.next){ 245 Object k; 246 if(e.hash == hash &&((k = e.key)== key || key.equals(k))){ 247 V oldValue = e.value; 248 e.value = value; 249 e.recordAccess(this); 250 return oldValue; 251 } 252 } 253 modCount++; 254 addEntry(hash, key, value, i); 255 returnnull; 256 } 257 /** 258 * Offloaded version of put for null keys 259 */ 260 private V putForNullKey(V value){ 261 for(Entry<K,V> e = table[0]; e !=null; e = e.next){ 262 if(e.key ==null){ 263 V oldValue = e.value; 264 e.value = value; 265 e.recordAccess(this); 266 return oldValue; 267 } 268 } 269 modCount++; 270 addEntry(0,null, value,0); 271 returnnull; 272 } 273 // These methods are used when serializing HashSets 274 int capacity(){return table.length;} 275 float loadFactor(){return loadFactor;} 276 } 277 278 HashTable类 279 280 publicclassHashtable<K,V> 281 extendsDictionary<K,V> 282 implementsMap<K,V>,Cloneable, java.io.Serializable{ 283 /** 284 * The hash table data. 285 */ 286 privatetransientEntry[] table; 287 /** 288 * The total number of entries in the hash table. 289 */ 290 privatetransientint count; 291 /** 292 * The table is rehashed when its size exceeds this threshold. (The 293 * value of this field is (int)(capacity * loadFactor).) 294 * 295 * @serial 296 */ 297 privateint threshold; 298 /** 299 * The load factor for the hashtable. 300 * 301 * @serial 302 */ 303 privatefloat loadFactor; 304 /** 305 * The number of times this Hashtable has been structurally modified 306 * Structural modifications are those that change the number of entries in 307 * the Hashtable or otherwise modify its internal structure (e.g., 308 * rehash). This field is used to make iterators on Collection-views of 309 * the Hashtable fail-fast. (See ConcurrentModificationException). 310 */ 311 privatetransientint modCount =0; 312 /** use serialVersionUID from JDK 1.0.2 for interoperability */ 313 privatestaticfinallong serialVersionUID =1421746759512286392L; 314 /** 315 * Constructs a new, empty hashtable with the specified initial 316 * capacity and the specified load factor. 317 * 318 * @param initialCapacity the initial capacity of the hashtable. 319 * @param loadFactor the load factor of the hashtable. 320 * @exception IllegalArgumentException if the initial capacity is less 321 * than zero, or if the load factor is nonpositive. 322 */ 323 publicHashtable(int initialCapacity,float loadFactor){ 324 if(initialCapacity <0) 325 thrownewIllegalArgumentException("Illegal Capacity: "+ 326 initialCapacity); 327 if(loadFactor <=0||Float.isNaN(loadFactor)) 328 thrownewIllegalArgumentException("Illegal Load: "+loadFactor); 329 if(initialCapacity==0) 330 initialCapacity =1; 331 this.loadFactor = loadFactor; 332 table =newEntry[initialCapacity]; 333 threshold =(int)(initialCapacity * loadFactor); 334 } 335 /** 336 * Constructs a new, empty hashtable with the specified initial capacity 337 * and default load factor (0.75). 338 * 339 * @param initialCapacity the initial capacity of the hashtable. 340 * @exception IllegalArgumentException if the initial capacity is less 341 * than zero. 342 */ 343 publicHashtable(int initialCapacity){ 344 this(initialCapacity,0.75f); 345 } 346 /** 347 * Constructs a new, empty hashtable with a default initial capacity (11) 348 * and load factor (0.75). 349 */ 350 publicHashtable(){ 351 this(11,0.75f); 352 } 353 /** 354 * Constructs a new hashtable with the same mappings as the given 355 * Map. The hashtable is created with an initial capacity sufficient to 356 * hold the mappings in the given Map and a default load factor (0.75). 357 * 358 * @param t the map whose mappings are to be placed in this map. 359 * @throws NullPointerException if the specified map is null. 360 * @since 1.2 361 */ 362 publicHashtable(Map<?extends K,?extends V> t){ 363 this(Math.max(2*t.size(),11),0.75f); 364 putAll(t); 365 } 366 /** 367 * Returns the number of keys in this hashtable. 368 * 369 * @return the number of keys in this hashtable. 370 */ 371 publicsynchronizedint size(){ 372 return count; 373 } 374 /** 375 * Tests if this hashtable maps no keys to values. 376 * 377 * @return <code>true</code> if this hashtable maps no keys to values; 378 * <code>false</code> otherwise. 379 */ 380 publicsynchronizedboolean isEmpty(){ 381 return count ==0; 382 } 383 /** 384 * Returns an enumeration of the keys in this hashtable. 385 * 386 * @return an enumeration of the keys in this hashtable. 387 * @see Enumeration 388 * @see #elements() 389 * @see #keySet() 390 * @see Map 391 */ 392 publicsynchronizedEnumeration<K> keys(){ 393 returnthis.<K>getEnumeration(KEYS); 394 }
- HashTable的方法是同步的,HashMap不能同步,所以在线程多的场合要使用HashTable;
- HashTable不允许空值(key和value都不可以为null),hashmap则可以为null
- HashTable有一个contains()的方法,功能和containsValue()一样
- HashTable使用Enumeration,而HashMap使用Iterator
- HashTabe中的hash数组默认大小为11,增长方式为old*2+1,hashmap的hash为16,是2的指数倍
- 哈希值的使用不同,HashTable直接使用对象hashcode,而HashMap会重新计算hash值