JDK源码阅读——模拟HashMap

曾经终败给现在 2022-07-12 07:00 352阅读 0赞

阅读过JDK源码,发现其实HashMap的实现就是一张散列表,由数组和链表组成,下面可以用简单的代码去模拟一下hashMap的插入和获取过程

  1. package yyf.java.util.Map.model;
  2. /**
  3. * Map的模拟
  4. *
  5. * @author yuyufeng
  6. *
  7. * @param <K>
  8. * @param <V>
  9. */
  10. public class MyMap<K, V> {
  11. /**
  12. * 当length = 2^n时,不同的hash值发生碰撞的概率比较小,这样就会使得数据在table数组中分布较均匀,查询速度也较快
  13. * (扩容时其中的indexFor -> h & (length-1)) 这里就不做处理,模拟时只做%length
  14. */
  15. static final int ARRAYMAX = 16;
  16. /**
  17. * 构造函数初始化数组
  18. */
  19. public MyMap() {
  20. table = new Node[ARRAYMAX];
  21. }
  22. /**
  23. * 数组
  24. */
  25. Node<K, V>[] table;
  26. /**
  27. * 获取key的hash值
  28. *
  29. * @param key
  30. * @return
  31. */
  32. static final int hash(Object key) {
  33. int h;
  34. return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
  35. }
  36. /**
  37. * 根据key获取value
  38. *
  39. * @param key
  40. * @return
  41. */
  42. public V get(Object key) {
  43. int index = hash(key) % ARRAYMAX;
  44. Node<K, V> p = table[index];
  45. while (p != null) {
  46. if (p.key.equals(key)) {
  47. break;
  48. }
  49. p = p.next;
  50. }
  51. if (p == null) {
  52. return null;
  53. }
  54. return p.value;
  55. }
  56. /**
  57. * put key-vlaue
  58. *
  59. * @param key
  60. * @param value
  61. */
  62. public void put(K key, V value) {
  63. Node<K, V> p, q;
  64. // 计算key需要存放的在table数组中的位置
  65. int index = hash(key) % ARRAYMAX;
  66. // 每个table都挂上node,node的如何均匀分布、如何效率这里不做要求
  67. if (table[index] == null) {
  68. table[index] = new Node(hash(key), key, value, null);
  69. } else {
  70. q = table[index];
  71. // p = q.next;
  72. p = q;
  73. boolean flag = true;
  74. while (p != null) {
  75. // 如果已经存在,则覆盖
  76. if (key.equals(p.key)) {
  77. flag = false;
  78. p.value = value;
  79. break;
  80. }
  81. q = p;
  82. p = p.next;
  83. }
  84. if (flag) {
  85. p = new Node(hash(key), key, value, null);
  86. q.next = p;
  87. }
  88. }
  89. }
  90. /**
  91. * 打印所有key-value
  92. */
  93. public void printKVs() {
  94. Node<K, V> p;
  95. for (int i = 0; i < ARRAYMAX; i++) {
  96. p = table[i];
  97. System.out.println("[table] " + i + " ->");
  98. while (p != null) {
  99. System.out.println(p.key + " " + p.value);
  100. p = p.next;
  101. }
  102. }
  103. }
  104. /**
  105. * 删除key-value
  106. *
  107. * @param key
  108. * @return
  109. */
  110. public V remove(Object key) {
  111. int index = hash(key) % ARRAYMAX;
  112. Node<K, V> p = table[index];
  113. Node<K, V> q;
  114. q = p;
  115. while (p != null) {
  116. if (p.key.equals(key)) {
  117. q.next = p.next;
  118. break;
  119. }
  120. q = p;
  121. p = p.next;
  122. }
  123. if (p == null) {
  124. return null;
  125. }
  126. return p.value;
  127. }
  128. }
  129. class Node<K, V> {
  130. int hash;
  131. K key;
  132. V value;
  133. Node<K, V> next;
  134. public Node() {
  135. }
  136. public Node(int hash, K key, V value, Node<K, V> next) {
  137. this.hash = hash;
  138. this.key = key;
  139. this.value = value;
  140. this.next = next;
  141. }
  142. }

test.java

  1. package yyf.java.util.Map.model;
  2. public class Test {
  3. public static void main(String[] args) {
  4. MyMap<String, String> map = new MyMap<>();
  5. map.put("k1", "v1");
  6. map.put("k11", "v11");
  7. map.put("k2", "v2");
  8. map.put("k22", "v22");
  9. map.put("k3", "v3");
  10. map.put("k33", "v33");
  11. map.put("k23", "v23");
  12. map.put("k4", "v4");
  13. map.put("k41", "v41");
  14. map.put("k5", "value5");
  15. map.put("kabc", "vabc");
  16. map.put("k4", "v5");// 塞入相同的key,则覆盖
  17. System.out.println("删除k22: "+map.remove("k22"));
  18. map.printKVs();
  19. System.out.println("##获取key:k4 " + map.get("k4"));
  20. System.out.println("##获取key:k6 " + map.get("k6"));
  21. // System.out.println(hash("dasd"));
  22. }
  23. static final int hash(Object key) {
  24. int h;
  25. return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
  26. }
  27. }

console

  1. 删除k22: v22
  2. [table] 0 ->
  3. [table] 1 ->
  4. [table] 2 ->
  5. [table] 3 ->
  6. [table] 4 ->
  7. [table] 5 ->
  8. kabc vabc
  9. [table] 6 ->
  10. k1 v1
  11. [table] 7 ->
  12. k2 v2
  13. [table] 8 ->
  14. k3 v3
  15. [table] 9 ->
  16. k4 v5
  17. k41 v41
  18. [table] 10 ->
  19. k11 v11
  20. k33 v33
  21. k5 value5
  22. [table] 11 ->
  23. [table] 12 ->
  24. [table] 13 ->
  25. k23 v23
  26. [table] 14 ->
  27. [table] 15 ->
  28. ##获取key:k4 v5
  29. ##获取key:k6 null

发表评论

表情:
评论列表 (有 0 条评论,352人围观)

还没有评论,来说两句吧...

相关阅读