当前位置:   article > 正文

手写HashMap+HashMap原理解说(一)_c++ 手写hashmap

c++ 手写hashmap

    最近看到一个面试题:手写HashMap,第一次写这个东西,觉得无从下手,上网copy了很多代码,复杂是复杂,就是有错,put进去的东西,并不能get出来,无奈之下自己写,以下是实现了简单的get()和put()方法,先上传,下次把扩容等功能补上。

    写之前最好先理解一下原理,可以少走弯路,先新建16个桶即bucket(16是源码默认的,可以自定义),给桶分别标上1~16标号,put一个键值对之后,用key的hash值对16取余,结果肯定也是一个1~16范围内的数值,把这对键值对放到取余后的值对应的那个的桶里(注意,不可能为每一个hash值都创建一个桶,那样的话代价太大,这里只创建了16个桶,所以很有可能一个桶里放入多个键值对;如果偏巧那个桶里是空的,直接把key、value放进去ok的,如果桶不为空,就要一个一个比对桶里原有的key是否和现在要放进去的key是同一个(即hash值相同且equals为true),如果是同一个,那么就用新的value覆盖替换原来的value就行,如果遍历完了,没有一个相同的key,那么就放到所有key的最后面(据说jdk1.8之后是放在最前面,具体还没有研究到),这样有多个键值对的桶里就形成了一个链表结构,而多个桶之间是数组元素的关系,所以说hashmap就是数组+链表结构。

  1. public interface MyMap<K, V> {
  2. V put(K key, V value);
  3. V get(K key);
  4. interface Entry<K, V> {
  5. K getKey();
  6. V getValue();
  7. }
  8. }
  1. public class MyHashMap<K, V> implements MyMap<K, V> {
  2. private static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
  3. private static final float DEFAULT_LOAD_FACTOR = 0.75f;
  4. private float loadFactor = 0;
  5. private int initCapacity = 0;
  6. private Entry<K, V>[] table = null;
  7. public MyHashMap() {
  8. this.loadFactor = DEFAULT_LOAD_FACTOR;
  9. this.initCapacity = DEFAULT_INITIAL_CAPACITY;
  10. table = new Entry[this.initCapacity];
  11. }
  12. public MyHashMap(int initCapacity, float loadFactor) {
  13. this.loadFactor = loadFactor;
  14. this.initCapacity = initCapacity;
  15. table = new Entry[this.initCapacity];
  16. }
  17. private int hash(K key) {
  18. int h;
  19. return (key == null) ? 0 : Math.abs((h = key.hashCode())) ^ (h >>> 16);
  20. }
  21. @Override
  22. public V put(K key, V value) {
  23. int index = hash(key) % initCapacity;
  24. if (table[index] != null) {
  25. Entry<K, V> e = table[index];
  26. Entry<K, V> e2 = null;
  27. while (e != null) {
  28. if (hash(e.key) == hash(key) && e.key.equals(key)) {
  29. e.value = value;
  30. return value;
  31. }
  32. e2 = e;
  33. e = e.next;
  34. }
  35. e2.next = new Entry<>(key, value, null, index);
  36. } else {
  37. Entry<K, V> e = new Entry<>(key, value, null, index);
  38. table[index] = e;
  39. }
  40. return value;
  41. }
  42. @Override
  43. public V get(K key) {
  44. int index = hash(key) % initCapacity;
  45. Entry<K, V> e = table[index];
  46. if (e == null) {
  47. return null;
  48. }
  49. while (e != null) {
  50. if (e.key == null && key == null ||
  51. hash(e.key) == hash(key) && e.key.equals(key)) {
  52. return e.value;
  53. }
  54. e = e.next;
  55. }
  56. return null;
  57. }
  58. class Entry<K, V> implements MyMap.Entry<K, V> {
  59. K key;
  60. V value;
  61. Entry<K, V> next;
  62. int index;//记录下标
  63. Entry(K k, V v, Entry<K, V> next, int inx) {
  64. this.key = k;
  65. this.value = v;
  66. this.index = inx;
  67. this.next = next;
  68. }
  69. public K getKey() {
  70. return key;
  71. }
  72. public V getValue() {
  73. return value;
  74. }
  75. public Entry getNext() {
  76. return next;
  77. }
  78. }
  79. }
  1. public class Test {
  2. public static void main(String[] args) {
  3. // Map<String, String> map = new HashMap();
  4. // map.put("name","sophia");
  5. // map.put("age", "18");
  6. // System.out.println(map.get("name"));
  7. // System.out.println(map.get("age"));
  8. MyMap<String, Object> map = new MyHashMap<>();
  9. map.put("name", "sophia");
  10. map.put("age", 18);
  11. map.put("hahaha", "hehehe");
  12. map.put("hehehe", "lalala");
  13. map.put(null, "lalala");
  14. System.out.println(map.get("name"));
  15. System.out.println(map.get("age"));
  16. System.out.println(map.get("hahaha"));
  17. System.out.println(map.get("hehehe"));
  18. System.out.println(map.get(null));
  19. }
  20. }


声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
  

闽ICP备14008679号