Java HashMap源代码详解
Java HashMap源代码详解
HashMap链地址法确定存储位置
将所有关键字为同义词的记录存储在同一线性表中。假设某哈希函数产生的哈希地址在区间[0,m-1]上,则设立一个指针型向量Chain Chain Hash[m];
其每个分量的初始状态都是空指针。凡是哈希地址为i的记录都插入到头指针为ChainHash[i]的链表中。在列表中的插入位置可以在表头或表尾;也可以在中间,以保持同义词在同一线性表中按关键字有序。
例如:已知一组关键字为(19,14,23,01,68,20,84,27,55,11,10,79),则按哈希函数H(key)=key MOD 13 和链地址法处理冲突构造所得的哈希表,如下图所示:
Hash map=New HashMap();
HashMap基于散列表的实现。插入和查询“键值对”的开销是固定的。可以通过构造器设置容量capacity和负载因子load factor,以调整容器的性能。
说明:
数据存放在数组中,但物理存储是链式存储
数组成员成为格子,且每个格子的hash值的唯一的
每个格子可存放hash值相同的多对K-V,每对被称为桶(每个桶是唯一的即Map存放数据不可重复)
格子中的桶与桶之间是通过指针连接的(Map是无序的)
处理流程:
1、创建默认初始容量16,加载因子 (0.75)
2、通过public V put(K key, V value);先计算key的hash值,确定key所在的格子(如果为空则需要创建一个新桶存放K-V,不为空则覆盖旧桶)
3、每次创建一个桶则size大小进行记录,并在创建新桶后进行判断size与threshold阈值变量比较,如果size>threshold则需要扩充格子容量原来的2倍。
HashMap源码

1 package java2.util2; 2 3 import java.io.IOException; 4 import java.io.Serializable; 5 import java.util.AbstractCollection; 6 import java.util.AbstractSet; 7 import java.util.Collection; 8 import java.util.ConcurrentModificationException; 9 import java.util.Iterator; 10 import java.util.NoSuchElementException; 11 import java.util.Set; 12 /** 13 * HashMap 14 * @author wwl 15 * 16 * @param <K> 17 * @param <V> 18 */ 19 public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, 20 Cloneable, Serializable { 21 22 // 系统默认初始容量,必须是2的n次幂,这是出于优化考虑的 23 static final int DEFAULT_INITIAL_CAPACITY = 16; 24 25 // 系统默认最大容量2的30次幂1073741824 26 static final int MAXIMUM_CAPACITY = 1 << 30; 27 28 // 系统默认负载因子,可在构造函数中指定 29 static final float DEFAULT_LOAD_FACTOR = 0.75f; 30 31 // 用于存储的表,长度可以调整,且必须是2的n次幂 32 transient Entry[] table; 33 34 // 当前map的key-value映射数,也就是当前size 35 transient int size; 36 37 /** 38 * 表示HashMap所能容纳的key-value对极限,如果存储的size数大于了threshold,则需要扩容了 39 * 阈值 40 * @serial 41 */ 42 int threshold; 43 44 /** 45 * 哈希表的负载因子 46 * loadFactor是负载因子,增大值时可以减少Hash表(也就是Entry数组)所占用的内存空间, 47 * 但会增加查询数据时时间的开销,而查询是最频繁的操作,减小值时会提高数据查询的性能, 但是会增大Hash表所占用的内存空间,所以一般是默认的0.75 48 * 49 * @serial 50 */ 51 final float loadFactor; 52 53 /** 54 * 用于确保使用迭代器的时候,HashMap并未进行更改 55 */ 56 transient volatile int modCount; 57 58 /** 59 * 构造一个带指定初始容量和加载因子的空 HashMap 60 * 61 * @param initialCapacity 62 * 初始容量 63 * @param loadFactor 64 * 加载因子 65 * @throws IllegalArgumentException 66 * if the initial capacity is negative or the load factor is 67 * nonpositive 68 */ 69 public HashMap(int initialCapacity, float loadFactor) { 70 // 如果指定初始容量小于0,抛错 71 if (initialCapacity < 0) 72 throw new IllegalArgumentException("Illegal initial capacity: " 73 + initialCapacity); 74 // 如果初始容量大于系统默认最大容量,则初始容量为最大容量 75 if (initialCapacity > MAXIMUM_CAPACITY) 76 initialCapacity = MAXIMUM_CAPACITY; 77 // 如果loadFactor小于0,或loadFactor是NaN,则抛错 78 if (loadFactor <= 0 || Float.isNaN(loadFactor)) 79 throw new IllegalArgumentException("Illegal load factor: " 80 + loadFactor); 81 // 寻找一个2的k次幂capacity恰好大于initialCapacity 82 int capacity = 1; 83 while (capacity < initialCapacity) 84 // 计算出大于initialCapacity的最小的2的n次方值 85 capacity <<= 1; 86 87 this.loadFactor = loadFactor; 88 threshold = (int) (capacity * loadFactor);// 设置容量极限 89 // 创建一个capacity长度的数组用于保存数据 90 table = new Entry[capacity]; 91 init(); 92 } 93 94 /** 95 * 构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap 96 * 97 * @param initialCapacity 98 * 初始容量 99 * @throws IllegalArgumentException 100 * if the initial capacity is negative. 101 */ 102 public HashMap(int initialCapacity) { 103 this(initialCapacity, DEFAULT_LOAD_FACTOR); 104 } 105 106 /** 107 * 构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap 108 */ 109 public HashMap() { 110 this.loadFactor = DEFAULT_LOAD_FACTOR; 111 threshold = (int) (DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR); 112 table = new Entry[DEFAULT_INITIAL_CAPACITY]; 113 init(); 114 } 115 116 /** 117 * 构造一个映射关系与指定 Map 相同的新 HashMap 118 * 119 */ 120 public HashMap(Map<? extends K, ? extends V> m) { 121 this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, 122 DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR); 123 putAllForCreate(m); 124 } 125 /** 126 * 初始化 127 */ 128 void init() { 129 } 130 131 /** 132 * HashMap的哈希函数 133 * 预处理hash值,避免较差的离散hash序列 134 * @param h 135 * @return 136 */ 137 static int hash(int h) { 138 h ^= (h >>> 20) ^ (h >>> 12); 139 return h ^ (h >>> 7) ^ (h >>> 4); 140 } 141 142 /** 143 * 返回对应hash值得索引 144 * 根据key的hash值获取哈希地址 145 * @param h 146 * @param length 147 * @return 148 */ 149 static int indexFor(int h, int length) { 150 //由于length是2的n次幂,所以h & (length-1)相当于h % length 151 return h & (length - 1); 152 } 153 154 /** 155 * 返回当前map的key-value映射数,也就是当前size 156 */ 157 public int size() { 158 return size; 159 } 160 /** 161 * 该HashMap是否是空的,如果size为0,则为空 162 */ 163 public boolean isEmpty() { 164 return size == 0; 165 } 166 /** 167 * 返回指定键所映射的值;如果对于该键来说,此映射不包含任何映射关系,则返回 null 168 * 先根据输入的key计算hash值,得出index,找到对应数组节点,在节点内的链表结构中遍历寻找所求数据 169 */ 170 public V get(Object key) { 171 if (key == null) 172 return getForNullKey(); 173 int hash = hash(key.hashCode()); 174 // 得到对应的hash值的桶,如果这个桶不是,就通过next获取下一个桶 175 for (Entry<K, V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { 176 Object k; 177 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) 178 return e.value; 179 } 180 return null; 181 } 182 /** 183 * 如果要得到key为null的值,则通过这个获取 184 * @return 185 */ 186 private V getForNullKey() { 187 for (Entry<K, V> e = table[0]; e != null; e = e.next) { 188 if (e.key == null) 189 return e.value; 190 } 191 return null; 192 } 193 194 /** 195 * 如果此映射包含对于指定键的映射关系,则返回 true 196 */ 197 public boolean containsKey(Object key) { 198 return getEntry(key) != null; 199 } 200 201 /** 202 * 通过key获取一个value 203 */ 204 final Entry<K, V> getEntry(Object key) { 205 // 如果key为null,则hash为0,否则用hash函数预处理 206 int hash = (key == null) ? 0 : hash(key.hashCode()); 207 // 先得到对应的hash值的桶,再比较key值如果这个桶不是,就通过next获取下一个桶 208 for (Entry<K, V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { 209 Object k; 210 if (e.hash == hash 211 && ((k = e.key) == key || (key != null && key.equals(k)))) 212 return e; 213 } 214 return null; 215 } 216 217 /** 218 * 存放K-V 219 * 采用链地址法 220 * 哈希值[0,m-1],先计算hash根据哈希存放到对应hash值桶中,可以存放多个相同的hash 221 * 在此映射中关联指定值与指定键。如果该映射以前包含了一个该键的映射关系,则旧值被替换 222 */ 223 public V put(K key, V value) { 224 if (key == null) 225 return putForNullKey(value); 226 int hash = hash(key.hashCode()); 227 int i = indexFor(hash, table.length); 228 // 先得到对应的hash值的格子,判断该hash值的格子中下是否已经存储数据,若不为空则已存在,则新数据需要通过next获取下一个桶 229 for (Entry<K, V> e = table[i]; e != null; e = e.next) { 230 Object k; 231 // 如果hash相同并且key相同 ,则旧值被替换 232 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 233 V oldValue = e.value; 234 e.value = value; 235 e.recordAccess(this); 236 return oldValue; 237 } 238 } 239 240 modCount++; 241 addEntry(hash, key, value, i); 242 return null; 243 } 244 245 /** 246 * 当key为空时进行存放 247 * 物理存储采用链表结构 248 */ 249 private V putForNullKey(V value) { 250 for (Entry<K, V> e = table[0]; e != null; e = e.next) { 251 if (e.key == null) { 252 V oldValue = e.value; 253 e.value = value; 254 e.recordAccess(this); 255 return oldValue; 256 } 257 } 258 modCount++; 259 addEntry(0, null, value, 0); 260 return null; 261 } 262 263 /** 264 * 检查当前已创建的桶是存在 265 */ 266 private void putForCreate(K key, V value) { 267 int hash = (key == null) ? 0 : hash(key.hashCode()); 268 int i = indexFor(hash, table.length); 269 270 // 遍历所有桶 271 for (Entry<K, V> e = table[i]; e != null; e = e.next) { 272 Object k; 273 // 如果有hash相同,且key相同,那么则不需要创建新的桶,退出 274 if (e.hash == hash 275 && ((k = e.key) == key || (key != null && key.equals(k)))) { 276 e.value = value; 277 return; 278 } 279 } 280 //否则,不存在hash值桶需要创建新的桶 281 createEntry(hash, key, value, i); 282 } 283 /** 284 * 根据Map创建所有对应的桶 285 * @param m 286 */ 287 private void putAllForCreate(Map<? extends K, ? extends V> m) { 288 for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m 289 .entrySet().iterator(); i.hasNext();) { 290 Map.Entry<? extends K, ? extends V> e = i.next(); 291 putForCreate(e.getKey(), e.getValue()); 292 } 293 } 294 295 /** 296 * 根据新的容量来resize这个HashMap 297 * @param newCapacity 298 */ 299 void resize(int newCapacity) { 300 Entry[] oldTable = table; 301 int oldCapacity = oldTable.length; 302 if (oldCapacity == MAXIMUM_CAPACITY) { 303 threshold = Integer.MAX_VALUE; 304 return; 305 } 306 // 根据新的容量新建一个table 307 Entry[] newTable = new Entry[newCapacity]; 308 // 将table转换成newTable 309 transfer(newTable); 310 // 将table设置newTable 311 table = newTable; 312 // 设置阈值 313 threshold = (int) (newCapacity * loadFactor); 314 } 315 316 /** 317 * 动态扩展后,将所有格子里的桶都放到新的table中 318 */ 319 void transfer(Entry[] newTable) { 320 Entry[] src = table; 321 int newCapacity = newTable.length; 322 for (int j = 0; j < src.length; j++) { 323 Entry<K, V> e = src[j]; 324 if (e != null) { 325 src[j] = null; 326 do { 327 Entry<K, V> next = e.next; 328 int i = indexFor(e.hash, newCapacity); 329 e.next = newTable[i]; 330 newTable[i] = e; 331 e = next; 332 } while (e != null); 333 } 334 } 335 } 336 337 /** 338 * 将另一个Map对象copy到当前对象 339 * 将指定映射的所有映射关系复制到此映射中,这些映射关系将替换此映射目前针对指定映射中所有键的所有映射关系 340 */ 341 public void putAll(Map<? extends K, ? extends V> m) { 342 // 需要复制多少个映射关系 343 int numKeysToBeAdded = m.size(); 344 if (numKeysToBeAdded == 0) 345 return; 346 347 // 如果要复制的映射关系比阈值还要多 348 if (numKeysToBeAdded > threshold) { 349 // 重新计算新的容量先resize 350 int targetCapacity = (int) (numKeysToBeAdded / loadFactor + 1); 351 if (targetCapacity > MAXIMUM_CAPACITY) 352 targetCapacity = MAXIMUM_CAPACITY; 353 int newCapacity = table.length; 354 while (newCapacity < targetCapacity) 355 newCapacity <<= 1; 356 if (newCapacity > table.length) 357 resize(newCapacity); 358 } 359 // 迭代将key-value映射放进该HashMap 360 for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m 361 .entrySet().iterator(); i.hasNext();) { 362 Map.Entry<? extends K, ? extends V> e = i.next(); 363 put(e.getKey(), e.getValue()); 364 } 365 } 366 367 /** 368 * 从此映射中移除指定键的映射关系(如果存在) 369 */ 370 public V remove(Object key) { 371 Entry<K, V> e = removeEntryForKey(key); 372 return (e == null ? null : e.value); 373 } 374 375 /** 376 * 根据key删除桶,并返回对应value 377 */ 378 final Entry<K, V> removeEntryForKey(Object key) { 379 int hash = (key == null) ? 0 : hash(key.hashCode()); 380 int i = indexFor(hash, table.length); 381 // 找到对应的格子 382 Entry<K, V> prev = table[i]; 383 Entry<K, V> e = prev; 384 // 遍历所有桶 385 while (e != null) { 386 Entry<K, V> next = e.next; 387 Object k; 388 // 如果找到对应的桶 389 if (e.hash == hash 390 && ((k = e.key) == key || (key != null && key.equals(k)))) { 391 modCount++; 392 size--; 393 // 如果第一个就是要删的桶 394 if (prev == e) 395 // 则table[i]等于下一个桶 396 table[i] = next; 397 else 398 // 否则上一个桶的下一个等于下一个桶 399 prev.next = next; 400 e.recordRemoval(this); 401 return e; 402 } 403 prev = e; 404 e = next; 405 } 406 407 return e; 408 } 409 410 /** 411 * 根据桶来删除map里的值 412 */ 413 final Entry<K, V> removeMapping(Object o) { 414 // 如果o不是Map.Entry的实例,则退出返回null 415 if (!(o instanceof Map.Entry)) 416 return null; 417 // 将o转成Map.Entry 418 Map.Entry<K, V> entry = (Map.Entry<K, V>) o; 419 Object key = entry.getKey(); 420 int hash = (key == null) ? 0 : hash(key.hashCode()); 421 int i = indexFor(hash, table.length); 422 Entry<K, V> prev = table[i]; 423 Entry<K, V> e = prev; 424 425 while (e != null) { 426 Entry<K, V> next = e.next; 427 if (e.hash == hash && e.equals(entry)) { 428 modCount++; 429 size--; 430 if (prev == e) 431 table[i] = next; 432 else 433 prev.next = next; 434 e.recordRemoval(this); 435 return e; 436 } 437 prev = e; 438 e = next; 439 } 440 441 return e; 442 } 443 444 /** 445 * 从此映射中移除所有映射关系。此调用返回后,映射将为空 446 */ 447 public void clear() { 448 modCount++; 449 Entry[] tab = table; 450 // 遍历table中的所有格子,然偶后设为nul 451 for (int i = 0; i < tab.length; i++) 452 tab[i] = null; 453 size = 0; 454 } 455 456 /** 457 * 如果此映射将一个或多个键映射到指定值,则返回 true 458 */ 459 public boolean containsValue(Object value) { 460 // 如果value为空,则返回containsNullValue函数的返回值 461 if (value == null) 462 return containsNullValue(); 463 464 Entry[] tab = table; 465 // 遍历table所有格子(链表) 466 for (int i = 0; i < tab.length; i++) 467 // 遍历链表中的每个桶 468 for (Entry e = tab[i]; e != null; e = e.next) 469 // 如果值相同,则返回true 470 if (value.equals(e.value)) 471 return true; 472 return false; 473 } 474 475 /** 476 * 对value为null的处理 477 */ 478 private boolean containsNullValue() { 479 Entry[] tab = table; 480 for (int i = 0; i < tab.length; i++) 481 for (Entry e = tab[i]; e != null; e = e.next) 482 if (e.value == null) 483 return true; 484 return false; 485 } 486 487 /** 488 * 返回此 HashMap 实例的浅表副本:并不复制键和值本身 489 */ 490 public Object clone() { 491 HashMap<K, V> result = null; 492 try { 493 result = (HashMap<K, V>) super.clone(); 494 } catch (CloneNotSupportedException e) { 495 // assert false; 496 } 497 result.table = new Entry[table.length]; 498 result.entrySet = null; 499 result.modCount = 0; 500 result.size = 0; 501 result.init(); 502 result.putAllForCreate(this); 503 504 return result; 505 } 506 /** 507 * 内置class输入对象,也就是桶 508 * @author wwl 509 * 510 * @param <K> 511 * @param <V> 512 */ 513 static class Entry<K, V> implements Map.Entry<K, V> { 514 final K key; 515 V value; 516 Entry<K, V> next; 517 final int hash; 518 519 /** 520 * 构造函数 521 */ 522 Entry(int h, K k, V v, Entry<K, V> n) { 523 value = v; 524 next = n; 525 key = k; 526 hash = h; 527 } 528 /** 529 * 返回key 530 */ 531 public final K getKey() { 532 return key; 533 } 534 /** 535 * 返回value 536 */ 537 public final V getValue() { 538 return value; 539 } 540 /** 541 * 设置value 542 */ 543 public final V setValue(V newValue) { 544 V oldValue = value; 545 value = newValue; 546 return oldValue; 547 } 548 /** 549 * 是否相同,比对的是key与value 550 */ 551 public final boolean equals(Object o) { 552 // 如果o不是Map.Entry的实例,那么肯定不相同了 553 if (!(o instanceof Map.Entry)) 554 return false; 555 // 将o转成Map.Entry 556 Map.Entry e = (Map.Entry) o; 557 // 得到key和value对比是否相同,相同则为true 558 Object k1 = getKey(); 559 Object k2 = e.getKey(); 560 if (k1 == k2 || (k1 != null && k1.equals(k2))) { 561 Object v1 = getValue(); 562 Object v2 = e.getValue(); 563 if (v1 == v2 || (v1 != null && v1.equals(v2))) 564 return true; 565 } 566 return false; 567 } 568 569 public final int hashCode() { 570 return (key == null ? 0 : key.hashCode()) 571 ^ (value == null ? 0 : value.hashCode()); 572 } 573 574 public final String toString() { 575 return getKey() + "=" + getValue(); 576 } 577 578 /** 579 * 使用该方法证明该key已经在该map中 580 */ 581 void recordAccess(HashMap<K, V> m) { 582 } 583 584 /** 585 * 该方法记录该key已经被移除了 586 */ 587 void recordRemoval(HashMap<K, V> m) { 588 } 589 } 590 591 /** 592 * 添加一个新的桶来保存该key和value 593 */ 594 void addEntry(int hash, K key, V value, int bucketIndex) { 595 Entry<K, V> e = table[bucketIndex]; 596 table[bucketIndex] = new Entry<K, V>(hash, key, value, e); 597 if (size++ >= threshold) 598 resize(2 * table.length); 599 } 600 601 /** 602 * 新建一个桶,该方法不需要判断是否超过阈值 603 */ 604 void createEntry(int hash, K key, V value, int bucketIndex) { 605 Entry<K, V> e = table[bucketIndex]; 606 table[bucketIndex] = new Entry<K, V>(hash, key, value, e); 607 size++; 608 } 609 /** 610 * 内部class HashIterator迭代器 611 * @author wwl 612 * 613 * @param <E> 614 */ 615 private abstract class HashIterator<E> implements Iterator<E> { 616 Entry<K, V> next; // 下一个桶 617 int expectedModCount; // 保护HashMap没有变更 618 int index; // 当前的索引 619 Entry<K, V> current; // 当前的桶 620 621 HashIterator() { 622 // 保存modCount,因为如果HashMap进行了任何操作modCount都会增加,所以如果发现modCount变化了,就可以抛出失败 623 expectedModCount = modCount; 624 if (size > 0) { // 进入第一个桶 625 Entry[] t = table; 626 while (index < t.length && (next = t[index++]) == null) 627 ; 628 } 629 } 630 /** 631 * 判断有没有下一个桶 632 */ 633 @Override 634 public final boolean hasNext() { 635 return next != null; 636 } 637 /** 638 * 获取下一个桶 639 * @return 640 */ 641 final Entry<K, V> nextEntry() { 642 if (modCount != expectedModCount) 643 throw new ConcurrentModificationException(); 644 Entry<K, V> e = next; 645 // 如果next为空,抛出失败 646 if (e == null) 647 throw new NoSuchElementException(); 648 // 如果next.next为空,将next定义为下一个格子中的桶,否则为该格子的下一个桶 649 if ((next = e.next) == null) { 650 Entry[] t = table; 651 while (index < t.length && (next = t[index++]) == null) 652 ; 653 } 654 current = e; 655 return e; 656 } 657 /** 658 * 删除 659 */ 660 @Override 661 public void remove() { 662 // 如果当前为空,抛出 663 if (current == null) 664 throw new IllegalStateException(); 665 // modCount变化了,抛出失败 666 if (modCount != expectedModCount) 667 throw new ConcurrentModificationException(); 668 // 获得当前的key 669 Object k = current.key; 670 // 设置current为null 671 current = null; 672 // 删除掉对应key的元素 673 HashMap.this.removeEntryForKey(k); 674 // 重置expectedModCount 675 expectedModCount = modCount; 676 } 677 678 } 679 /** 680 * 内部class ValueIterator迭代器,重写next方法 681 * @author wwl 682 * 683 */ 684 private final class ValueIterator extends HashIterator<V> { 685 @Override 686 public V next() { 687 return nextEntry().value; 688 } 689 } 690 /** 691 * 内部class KeyIterator迭代器,重写next方法 692 * @author wwl 693 * 694 */ 695 private final class KeyIterator extends HashIterator<K> { 696 public K next() { 697 return nextEntry().getKey(); 698 } 699 } 700 /** 701 * 内部class EntryIterator迭代器,重写next方法 702 * @author wwl 703 * 704 */ 705 private final class EntryIterator extends HashIterator<Map.Entry<K, V>> { 706 public Map.Entry<K, V> next() { 707 return nextEntry(); 708 } 709 } 710 711 /** 712 * 定义对应的 iterator() 方法 713 * @return 714 */ 715 Iterator<K> newKeyIterator() { 716 return new KeyIterator(); 717 } 718 /** 719 * 定义对应的 iterator() 方法 720 * @return 721 */ 722 Iterator<V> newValueIterator() { 723 return new ValueIterator(); 724 } 725 /** 726 * 定义对应的 iterator() 方法 727 * @return 728 */ 729 Iterator<Map.Entry<K, V>> newEntryIterator() { 730 return new EntryIterator(); 731 } 732 733 // Views 734 735 private transient Set<Map.Entry<K, V>> entrySet = null; 736 737 /** 738 * 返回此映射中所包含的键的 Set 视图 739 */ 740 public Set<K> keySet() { 741 Set<K> ks = keySet; 742 return (ks != null ? ks : (keySet = new KeySet())); 743 } 744 745 /** 746 * 内部类KeySet对象 747 * @author wwl 748 * 749 */ 750 private final class KeySet extends AbstractSet<K> { 751 public Iterator<K> iterator() { 752 return newKeyIterator(); 753 } 754 755 public int size() { 756 return size; 757 } 758 759 public boolean contains(Object o) { 760 return containsKey(o); 761 } 762 763 public boolean remove(Object o) { 764 return HashMap.this.removeEntryForKey(o) != null; 765 } 766 767 public void clear() { 768 HashMap.this.clear(); 769 } 770 } 771 772 /** 773 * 返回此映射所包含的值的 Collection 视图 774 */ 775 public Collection<V> values() { 776 Collection<V> vs = values; 777 return (vs != null ? vs : (values = new Values())); 778 } 779 780 /** 781 * 内部类Values 782 * 783 * @author wwl 784 * 785 */ 786 private final class Values extends AbstractCollection<V> { 787 public Iterator<V> iterator() { 788 return newValueIterator(); 789 } 790 791 public int size() { 792 return size; 793 } 794 795 public boolean contains(Object o) { 796 return containsValue(o); 797 } 798 799 public void clear() { 800 HashMap.this.clear(); 801 } 802 } 803 804 /** 805 * 返回此映射所包含的映射关系的 Set 视图 806 */ 807 public Set<Map.Entry<K, V>> entrySet() { 808 return entrySet0(); 809 } 810 811 private Set<Map.Entry<K, V>> entrySet0() { 812 Set<Map.Entry<K, V>> es = entrySet; 813 return es != null ? es : (entrySet = new EntrySet()); 814 } 815 816 /** 817 * 内部类EntrySet对象 818 * 819 * @author wwl 820 * 821 */ 822 private final class EntrySet extends AbstractSet<Map.Entry<K, V>> { 823 public Iterator<Map.Entry<K, V>> iterator() { 824 return newEntryIterator(); 825 } 826 827 public boolean contains(Object o) { 828 if (!(o instanceof Map.Entry)) 829 return false; 830 Map.Entry<K, V> e = (Map.Entry<K, V>) o; 831 Entry<K, V> candidate = getEntry(e.getKey()); 832 return candidate != null && candidate.equals(e); 833 } 834 835 public boolean remove(Object o) { 836 return removeMapping(o) != null; 837 } 838 839 public int size() { 840 return size; 841 } 842 843 public void clear() { 844 HashMap.this.clear(); 845 } 846 } 847 848 /** 849 * 序列化方法 850 */ 851 private void writeObject(java.io.ObjectOutputStream s) throws IOException { 852 Iterator<Map.Entry<K, V>> i = (size > 0) ? entrySet0().iterator() 853 : null; 854 855 s.defaultWriteObject(); 856 857 s.writeInt(table.length); 858 859 s.writeInt(size); 860 861 if (i != null) { 862 while (i.hasNext()) { 863 Map.Entry<K, V> e = i.next(); 864 s.writeObject(e.getKey()); 865 s.writeObject(e.getValue()); 866 } 867 } 868 } 869 870 private static final long serialVersionUID = 362498820763181265L; 871 872 /** 873 * 通过序列读取对象 874 */ 875 private void readObject(java.io.ObjectInputStream s) throws IOException, 876 ClassNotFoundException { 877 s.defaultReadObject(); 878 879 int numBuckets = s.readInt(); 880 table = new Entry[numBuckets]; 881 882 init(); 883 884 int size = s.readInt(); 885 886 for (int i = 0; i < size; i++) { 887 K key = (K) s.readObject(); 888 V value = (V) s.readObject(); 889 putForCreate(key, value); 890 } 891 } 892 893 int capacity() { 894 return table.length; 895 } 896 897 float loadFactor() { 898 return loadFactor; 899 } 900 }
Map源码

1 package java2.util2; 2 3 import java.util.Collection; 4 import java.util.Set; 5 /** 6 * 重构Map接口 7 * @author wwl 8 * 9 * @param <K> 10 * @param <V> 11 */ 12 public interface Map<K, V> { 13 /** 14 * 返回map中键值对映射关系的数量 15 * 16 * @return 17 */ 18 int size(); 19 20 /** 21 * 如果此映射不包含键值的映射则返回true 22 * 23 * @return 24 */ 25 boolean isEmpty(); 26 27 /** 28 * 如果此映射包含指定键的映射关系,则返回 true 29 * 30 * @param key 31 * @return 32 */ 33 boolean containsKey(Object key); 34 35 /** 36 * 如果此映射将一个或多个键映射到指定值,则返回 true 37 * 38 * @param value 39 * @return 40 */ 41 boolean containsValue(Object value); 42 43 /** 44 * 指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null 45 * 允许null键null值 46 * @param key 47 * @return 48 */ 49 V get(Object key); 50 51 /** 52 * 存放键值对 53 * 54 * @param key 55 * @param value 56 * @return 57 */ 58 V put(K key, V value); 59 60 /** 61 * 以前与 key 关联的值;如果没有 key 的映射关系,则返回 null。 62 * 63 * @param key 64 * @return 65 */ 66 V remove(Object key); 67 68 /** 69 * 从此映射中移除所有映射关系 70 */ 71 void clear(); 72 73 /** 74 * 75 * @param m 76 */ 77 void putAll(Map<? extends K, ? extends V> m); 78 79 /** 80 * 返回此映射中包含的键的 Set 视图 81 * 82 * @return 83 */ 84 Set<K> keySet(); 85 86 /** 87 * 此映射中包含的值的 collection 视图 88 * @return 89 */ 90 Collection<V> values(); 91 92 /** 93 * 此映射中包含的映射关系的 set 视图 94 * @return 95 */ 96 Set<Map.Entry<K, V>> entrySet(); 97 98 interface Entry<K, V> { 99 /** 100 * 获取key值 101 * @return 102 */ 103 K getKey(); 104 105 /** 106 * 获取value值 107 * @return 108 */ 109 V getValue(); 110 111 /** 112 * 设置value值 113 * @param value 114 * @return 115 */ 116 V setValue(V value); 117 /** 118 * 如果指定的对象等于此映射项,则返回 true 119 * @param o 120 * @return 121 */ 122 boolean equals(Object o); 123 /** 124 * 此映射的哈希码值 125 * @return 126 */ 127 int hashCode(); 128 } 129 130 /** 131 * 如果指定的对象等于此映射,则返回 true 132 * @param o 133 * @return 134 */ 135 boolean equals(Object o); 136 137 /** 138 * 此映射的哈希码值 139 * @return 140 */ 141 int hashCode(); 142 }
AbstractMap源码

1 package java2.util2; 2 3 import java.util.AbstractCollection; 4 import java.util.AbstractSet; 5 import java.util.Collection; 6 import java.util.Iterator; 7 import java.util.Set; 8 9 10 11 12 public abstract class AbstractMap<K,V> implements Map<K,V> { 13 protected AbstractMap() { 14 } 15 16 @Override 17 public void clear() { 18 entrySet().clear(); 19 } 20 21 @Override 22 public boolean containsKey(Object key) { 23 Iterator<Entry<K,V>> i= entrySet().iterator(); 24 if(key==null){ 25 while(i.hasNext()){ 26 Entry<K,V> e=i.next(); 27 if(e.getKey()==null) 28 return true; 29 } 30 }else{ 31 while(i.hasNext()){ 32 Entry<K,V> e=i.next(); 33 if(key.equals(e.getKey())) 34 return true; 35 } 36 } 37 return false; 38 } 39 40 @Override 41 public boolean containsValue(Object value) { 42 Iterator<Entry<K,V>> i=entrySet().iterator(); 43 if(value==null){ 44 while(i.hasNext()){ 45 Entry<K,V> e=i.next(); 46 if(e.getValue()==null) 47 return true; 48 } 49 }else{ 50 while(i.hasNext()){ 51 Entry<K, V> e=i.next(); 52 if(value==e.getValue()) 53 return true; 54 } 55 } 56 return false; 57 } 58 59 @Override 60 public abstract Set<java2.util2.Map.Entry<K, V>> entrySet(); 61 62 @Override 63 //允许null键null值 64 public V get(Object key) { 65 Iterator<Entry<K, V>> i=entrySet().iterator(); 66 if(key==null){ 67 while(i.hasNext()){ 68 Entry<K, V> e=i.next(); 69 if(e.getKey()==null) 70 return e.getValue(); 71 72 } 73 }else{ 74 while(i.hasNext()){ 75 Entry<K, V> e=i.next(); 76 if(key.equals(e.getKey())) 77 return e.getValue(); 78 } 79 } 80 return null; 81 } 82 83 @Override 84 public boolean isEmpty() { 85 return size()==0; 86 } 87 //volatile也是变量修饰符,只能用来修饰变量。 88 //volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。 89 //而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。 90 //即通过改变就提交实现线程同步 91 92 //transient是类型修饰符,只能用来修饰字段。 93 //在对象序列化的过程中,标记为transient的变量不会被序列化。 94 transient volatile Set<K> keySet = null;//此处进行定义,表示每次生成set集合都是最新的 95 @Override 96 public Set<K> keySet() { 97 if(keySet==null){ 98 keySet=new AbstractSet<K>() { 99 @Override 100 public Iterator<K> iterator(){ 101 return new Iterator<K>(){ 102 private Iterator<Entry<K, V>> i=entrySet().iterator(); 103 104 public boolean hasNext(){ 105 return i.hasNext(); 106 } 107 public K next(){ 108 return i.next().getKey(); 109 } 110 public void remove(){ 111 i.remove(); 112 } 113 }; 114 } 115 116 @Override 117 public int size() { 118 return AbstractMap.this.size(); 119 } 120 @Override 121 public boolean contains(Object k) { 122 return AbstractMap.this.containsKey(k); 123 } 124 }; 125 } 126 return keySet; 127 } 128 129 @Override 130 public V put(K key, V value) { 131 throw new UnsupportedOperationException(); 132 } 133 134 @Override 135 public void putAll(Map<? extends K, ? extends V> m) { 136 for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) 137 put(e.getKey(), e.getValue()); 138 } 139 140 @Override 141 public V remove(Object key) { 142 Iterator<Entry<K, V>> i=entrySet().iterator(); 143 Entry<K, V> correctEntry =null; 144 if(key==null){ 145 while(i.hasNext()){ 146 Entry<K, V> e=i.next(); 147 if(e.getKey()==null) 148 correctEntry=e;//让引用指向空引用 149 } 150 }else{ 151 while(correctEntry==null&&i.hasNext()){ 152 Entry<K, V> e=i.next(); 153 if(key.equals(e.getKey())) 154 correctEntry=e; 155 } 156 } 157 return null; 158 } 159 160 @Override 161 public int size() { 162 return entrySet().size(); 163 } 164 165 transient volatile Collection<V> values = null; 166 167 @Override 168 public Collection<V> values() { 169 if (values == null) { 170 values = new AbstractCollection<V>() { 171 public Iterator<V> iterator() { 172 return new Iterator<V>() { 173 private Iterator<Entry<K,V>> i = entrySet().iterator(); 174 175 public boolean hasNext() { 176 return i.hasNext(); 177 } 178 179 public V next() { 180 return i.next().getValue(); 181 } 182 183 public void remove() { 184 i.remove(); 185 } 186 }; 187 } 188 189 public int size() { 190 return AbstractMap.this.size(); 191 } 192 193 public boolean contains(Object v) { 194 return AbstractMap.this.containsValue(v); 195 } 196 }; 197 } 198 return values; 199 } 200 201 @Override 202 public boolean equals(Object obj) { 203 if(obj==this) 204 return true; 205 if(!(obj instanceof Map)) 206 return false; 207 Map<K,V> m=(Map<K, V>) obj; 208 if(m.size()!=size()) 209 return false; 210 try { 211 Iterator<Entry<K,V>> i = entrySet().iterator(); 212 while (i.hasNext()) { 213 Entry<K,V> e = i.next(); 214 K key = e.getKey(); 215 V value = e.getValue(); 216 if (value == null) { 217 if (!(m.get(key)==null && m.containsKey(key))) 218 return false; 219 } else { 220 if (!value.equals(m.get(key))) 221 return false; 222 } 223 } 224 } catch (ClassCastException unused) { 225 return false; 226 } catch (NullPointerException unused) { 227 return false; 228 } 229 230 return true; 231 } 232 233 @Override 234 //所有map对象的hashcode相加 235 public int hashCode() { 236 int h = 0; 237 Iterator<Entry<K,V>> i = entrySet().iterator(); 238 while (i.hasNext()) 239 h += i.next().hashCode(); 240 return h; 241 } 242 243 @Override 244 public String toString() { 245 Iterator<Entry<K,V>> i = entrySet().iterator(); 246 if (! i.hasNext()) 247 return "{}"; 248 249 StringBuilder sb = new StringBuilder(); 250 sb.append('{'); 251 for (;;) { 252 Entry<K,V> e = i.next(); 253 K key = e.getKey(); 254 V value = e.getValue(); 255 sb.append(key == this ? "(this Map)" : key); 256 sb.append('='); 257 sb.append(value == this ? "(this Map)" : value); 258 if (! i.hasNext()) 259 return sb.append('}').toString(); 260 sb.append(", "); 261 } 262 } 263 264 @Override 265 protected Object clone() throws CloneNotSupportedException { 266 AbstractMap<K,V> result = (AbstractMap<K,V>)super.clone(); 267 result.keySet = null; 268 result.values = null; 269 return result; 270 } 271 272 }