• HashMap 实现总结


    1. Entry类中需包含键值的hash值,防止resize时的重复计算;
    2. Map容量为2的整幂,可使用位操作取代取余操作提高效率;
    3. resize时需要将原table的桶内数据置null,利于垃圾回收;
    4. hash函数考虑数据高位的影响,可减少冲突。
      1 public class MyHashMap<K, V> implements IMap<K, V> {
      2     static final float DEFAULT_LOAD_FACTOR = 0.75f;
      3     static final int DEFAULT_CAPACITY = 16;
      4 
      5     Entry<K, V>[] table;
      6     int size;
      7     /**
      8      * 装载因子
      9      */
     10     float loadFactor;
     11     /**
     12      * 实际的容量
     13      */
     14     int threshold;
     15 
     16     public MyHashMap() {
     17         this.loadFactor = DEFAULT_LOAD_FACTOR;
     18         this.threshold = (int) (DEFAULT_CAPACITY * loadFactor);
     19         table = new Entry[DEFAULT_CAPACITY];
     20     }
     21 
     22     public MyHashMap(int initialCapacity, float loadFactor) {
     23         /**
     24          * 缺少参数检查
     25          */
     26         int capacity = 1;
     27         while (capacity < initialCapacity) {
     28             capacity <<= 1;
     29         }
     30         this.loadFactor = loadFactor;
     31         this.threshold = (int) (capacity * loadFactor);
     32         table = new Entry[capacity];
     33     }
     34 
     35     public MyHashMap(int initialCapacity) {
     36         this(initialCapacity, DEFAULT_LOAD_FACTOR);
     37     }
     38 
     39     /**
     40      * 算术右移,计入高位影响
     41      */
     42     static int hash(int h) {
     43         return h ^ (h >>> 20) ^ (h >>> 12) ^ (h >>> 7) ^ (h >>> 4);
     44     }
     45 
     46     @Override
     47     public V put(K k, V v) {
     48         if (k == null) {
     49             putForNull(v);
     50         }
     51         int hash = hash(k.hashCode());
     52         int i = indexFor(hash, table.length);
     53         for (Entry<K, V> e = table[i]; e != null; e = e.next) {
     54             if (e.key.hashCode() == k.hashCode()
     55                     && (e.key == k || (k != null && k.equals(e.key)))) {
     56                 V oldValue = e.value;
     57                 e.value = v;
     58                 return oldValue;
     59             }
     60         }
     61         addEntry(k, v, i);
     62         return null;
     63     }
     64 
     65     private void addEntry(K k, V v, int index) {
     66         Entry<K, V> e = new Entry<K, V>(k, v, table[index]);
     67         table[index] = e;
     68         if (size++ > threshold) {
     69             resize(table.length * 2);
     70         }
     71     }
     72 
     73     void resize(int newCapacity) {
     74         Entry[] newTable = new Entry[newCapacity];
     75         transfer(newTable);
     76         table = newTable;
     77         threshold = (int) (newCapacity * loadFactor);
     78         System.out.println("resize()" + " current capacity: " + table.length);
     79     }
     80 
     81     void transfer(Entry[] newTable) {
     82         for (int i = 0; i < table.length; i++) {
     83             Entry<K, V> e = table[i];
     84             if (e != null) {
     85                 /**
     86                  * 需要將原table置为空,方可释放内存
     87                  */
     88                 table[i] = null;
     89                 do {
     90                     Entry<K, V> next = e.next;
     91                     /**
     92                      * 重复计算hash值,效率不高
     93                      */
     94                     int index = indexFor(hash(e.key.hashCode()),
     95                             newTable.length);
     96                     e.next = newTable[index];
     97                     newTable[index] = e;
     98                     e = next;
     99                 } while (e != null);
    100             }
    101         }
    102     }
    103 
    104     private V putForNull(V value) {
    105         // 未实现
    106         return value;
    107     }
    108 
    109     /**
    110      * 用位操作取代取余操作,前提是数组长度为2的幂次
    111      */
    112     private int indexFor(int hash, int length) {
    113         return hash & (length - 1);
    114     }
    115 
    116     @Override
    117     public V get(K k) {
    118         int hash = hash(k.hashCode());
    119         int index = indexFor(hash, table.length);
    120         Entry<K, V> e = table[index];
    121         while (e != null) {
    122             if (e.key.hashCode() == k.hashCode()
    123                     && (e.key == k || (k != null && k.equals(e.key)))) {
    124                 return e.value;
    125             }
    126             e = e.next;
    127         }
    128         return null;
    129     }
    130 
    131     static class Entry<K, V> {
    132         K key;
    133         V value;
    134         Entry<K, V> next;
    135         int hash;
    136 
    137         public Entry(K k, V v, Entry<K, V> n) {
    138             key = k;
    139             value = v;
    140             next = n;
    141             // hash = h;
    142         }
    143 
    144         public V setValue(V v) {
    145             V oldValue = value;
    146             value = v;
    147             return oldValue;
    148         }
    149 
    150         public boolean equals(Object o) {
    151             if (!(o instanceof MyHashMap.Entry)) {
    152                 return false;
    153             }
    154             Entry e = (Entry) o;
    155             Object k1 = e.key;
    156             Object k2 = key;
    157             if (k1 == k2 || (k1 != null && k1.equals(k2))) {
    158                 Object v1 = e.value;
    159                 Object v2 = value;
    160                 if (v1 == v2 || (v1 != v2 && v2.equals(v2))) {
    161                     return true;
    162                 }
    163             }
    164             return false;
    165         }
    166     }
    167 }
  • 相关阅读:
    Pycharm5注册方式
    五、监听共享目录文件
    三、python webservice
    二、Python安装扩展库
    一、Python安装下载
    test
    拖延
    要乐观对待生活
    乞讨者
    不要总是指责和埋怨
  • 原文地址:https://www.cnblogs.com/infinityu/p/3257378.html
Copyright © 2020-2023  润新知