706. 设计哈希映射

image.png

题解

  1. class MyHashMap {
  2. // 桶的大小
  3. private int hashKeySpace;
  4. // 桶
  5. private List<MyBucket<Integer, Integer>> hashTable;
  6. public MyHashMap() {
  7. // 初使化桶的大小
  8. this.hashKeySpace = 2048;
  9. // 初使化桶
  10. this.hashTable = new ArrayList<>();
  11. for (int i = 0; i < this.hashKeySpace; i++) {
  12. this.hashTable.add(new MyBucket<>());
  13. }
  14. }
  15. public void put(int key, int value) {
  16. // 获取桶内的链表,操作链表
  17. MyBucket bucket = getBucketByKey(key);
  18. bucket.update(new MyEntry<Integer, Integer>(key, value));
  19. }
  20. public int get(int key) {
  21. // 获取桶内的链表,再从链表中获取
  22. MyBucket bucket = getBucketByKey(key);
  23. MyEntry entry = bucket.get(key);
  24. if (entry != null) {
  25. return (int) entry.getValue();
  26. }
  27. return -1;
  28. }
  29. public void remove(int key) {
  30. // 获取桶内的链表,再从链表中删除节点
  31. MyBucket bucket = getBucketByKey(key);
  32. bucket.remove(key);
  33. }
  34. /**
  35. * 获取桶内的链表
  36. * @param key
  37. * @return
  38. */
  39. private MyBucket getBucketByKey(int key) {
  40. int hash = key % hashKeySpace;
  41. return hashTable.get(hash);
  42. }
  43. }
  44. // 节点结构
  45. class MyEntry<K, V> {
  46. final private K key;
  47. private V value;
  48. public MyEntry(K key, V value) {
  49. this.key = key;
  50. this.value = value;
  51. }
  52. public K getKey() {
  53. return key;
  54. }
  55. public V getValue() {
  56. return value;
  57. }
  58. public void setValue(V value) {
  59. this.value = value;
  60. }
  61. }
  62. // 桶里面的链表结构
  63. class MyBucket<K, V> {
  64. // 链表
  65. List<MyEntry<K, V>> linklist;
  66. public MyBucket() {
  67. linklist = new LinkedList<>();
  68. }
  69. /**
  70. * 为 map 的 put 提供服务,有可能是新增节点,也有可能是更新节点
  71. * @param entry 要放入链表的节点
  72. */
  73. public void update(MyEntry<K, V> entry) {
  74. // 标记是否是更新节点
  75. boolean exists = false;
  76. for (MyEntry<K, V> entryItem : linklist) {
  77. // 根据 key 判断节点是否已存在,如果存在则更新
  78. if (entry.getKey().equals(entryItem.getKey())) {
  79. entryItem.setValue(entry.getValue());
  80. exists = true;
  81. }
  82. }
  83. // 如果 key 不存在,新增节点
  84. if (!exists) linklist.add(entry);
  85. }
  86. /**
  87. * 根据 key 获取节点
  88. * @param key
  89. * @return 如果不存在返回 null
  90. */
  91. public MyEntry<K, V> get(int key) {
  92. for (MyEntry<K, V> entry : linklist) {
  93. if (entry.getKey().equals(key)) {
  94. return entry;
  95. }
  96. }
  97. return null;
  98. }
  99. /**
  100. * 根据 key 删除节点
  101. * @param key
  102. */
  103. public void remove(int key) {
  104. linklist.removeIf(entry -> entry.getKey().equals(key));
  105. }
  106. }