手写的hashMap

小弟我今天在群里看到有个大牛手写两个一个仿照redis思想的hashMap,自己想着,先记下来,以后慢慢研究,以下是代码。

/**
 * 仿redis思想,按照redis dict 实现自己的hashmap
 * 去除了原生的Java hashmap一些接口封装,只为实现功能
 * 目前实现了自动扩容和渐进式rehash
 * 自动收缩待实现
 * @author zzc
 * @date 2017/11/9
 */
public class MyHashMap<K,V> {
     private static int INIT_SIZE = 2;
     private static int THREAD_HOLD = 5;
     MyHashMap(){
          this.entries = new Entry[INIT_SIZE];
          this.size = INIT_SIZE;
          this.used = 0;
          this.mask = size-1;
          this.rehashidx = -1;
     }
     MyHashMap(int size){
          this.entries = new Entry[size];
          this.size = size;
          this.used = 0;
          this.mask = size-1;
          this.rehashidx = -1;
     }
     private Entry<K,V>[] entries;
     private int size;
     private int mask;
     private int used;
     private int rehashidx;
     private MyHashMap<K,V> back;
     private int hash(Object key) {
          return key.hashCode();
     }
     private int index(int hash){
          return hash&mask;
     }

     public void put(K k,V v){
          //扩展&收缩处理
          if((used/size)>=THREAD_HOLD){
               //此时需要扩展
               //计算新表大小
               if (back == null){
                    int i = 0;
                    while (used>>(++i)>0){

                    }
                    int newSize =1<<i;
                    back = new MyHashMap<>(newSize);
                    //标志开始rehash
                    this.rehashidx = 0;
               }
               transToNewTable();
               putToEntries(back,k,v);
               return;
          }
          putToEntries(this,k,v);

     }

     private void transToNewTable() {
          if (this.rehashidx<this.used){
               for (int i = 0 ;i<this.size;i++){
                    Entry<K, V> tmp = this.entries[i];
                    if (tmp != null){
                        this.entries[i] = tmp.next;
                         int index = back.index(tmp.k.hashCode());
                         Entry<K, V> btmp = back.entries[index];
                         tmp.next = btmp;
                         back.entries[index] = tmp;
                         back.used++;
                         this.rehashidx++;
                         break;
                    }
               }
               return;
          }
          copyEntries();
          this.rehashidx = -1;

     }

     private void copyEntries() {
          this.entries = back.entries;
          this.size = back.size;
          this.used = back.used;
          this.mask = back.mask;
          back.entries = null;
          back = null;
     }

     private void putToEntries(MyHashMap map, K k, V v) {
          //计算索引
          int index = map.index(hash(k));
          Entry curr = map.entries[index];
          if (curr == null){
               map.entries[index] = new Entry();
               map.entries[index].v=v;
               map.entries[index].k = k;
               map.used++;
               return;
          }
          if (curr.k.equals(k)){
               curr.v = v;
               return;
          }
          while (curr.hasNext()){
               curr = curr.next;
               if (curr.k.equals(k)) {
                    curr.v = v;
                    return;
               }
          }
          Entry<K, V> tmp = new Entry<>();
          tmp.k = k;
          tmp.v = v;
          curr.next = tmp;
          map.used++;
     }


     public V get(K k){
          //扩展&收缩处理
          if((used/size)>=THREAD_HOLD&&back!=null){
               transToNewTable();
               V ret = getEntries(this, k);
               if (ret!= null){
                    //rehash移动原来表kv到新表
                     return ret;
               }

               return getEntries(back,k);
          }

          return getEntries(this,k);
     }
     private V getEntries(MyHashMap map, K k) {
          int index = map.index(hash(k));
          Entry<K,V> curr = map.entries[index];
          if (curr == null){
               return null;
          }
          if (k.equals(curr.k)){
               return curr.v;
          }
          while (curr.hasNext()){
               curr = curr.next;
               if (curr.k.equals(k)){
                    return curr.v;
               }
          }
          return null;
     }

     class Entry<K,V>{
           K k;
          V v;
          Entry<K,V> next;
          boolean hasNext(){
               return next != null;
          }


     }

     public static void main(String[] args) {
          MyHashMap<String, String> myHashMap = new MyHashMap<>(2);
          myHashMap.put("name","张三");
          myHashMap.put("name1","李四");
          myHashMap.put("name2","李四");
          myHashMap.put("name3","李四");
          myHashMap.put("name4","李四");
          myHashMap.put("name5","李四");
          myHashMap.put("name6","李四");
          myHashMap.put("name7","李四");
          myHashMap.put("name8","李四");
          myHashMap.put("name9","李四");
          myHashMap.put("name10","李四");
          myHashMap.put("name11","李四");
          myHashMap.put("name12","李四");
          myHashMap.put("name13","李四");
          myHashMap.put("name14","李四");
          myHashMap.put("name15","李四");
          myHashMap.put("name16","李四");
          myHashMap.put("name17","李四");

          myHashMap.put("age","18");
          System.out.println(myHashMap.get("name"));
          System.out.println(myHashMap.get("name1"));
          System.out.println(myHashMap.get("name2"));
          System.out.println(myHashMap.get("name"));
          System.out.println(myHashMap.get("name"));
          System.out.println(myHashMap.get("name"));
          System.out.println(myHashMap.get("name"));
          System.out.println(myHashMap.get("name"));
          System.out.println(myHashMap.get("name"));
          System.out.println(myHashMap.get("name2"));
          System.out.println(myHashMap.get("name"));
          System.out.println(myHashMap.get("name"));
          System.out.println(myHashMap.get("name"));
          System.out.println(myHashMap.get("name1"));
          System.out.println(myHashMap.get("name"));




     }

}

猜你喜欢

转载自my.oschina.net/u/2543341/blog/1573964