小弟我今天在群里看到有个大牛手写两个一个仿照redis思想的hashMap,自己想着,先记下来,以后慢慢研究,以下是代码。
/** * 仿redis思想,按照redis dict 实现自己的hashmap * 去除了原生的Java hashmap一些接口封装,只为实现功能 * 目前实现了自动扩容和渐进式rehash * 自动收缩待实现 * @author zzc * @date 2017/11/9 */public class MyHashMap{ 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 [] entries; private int size; private int mask; private int used; private int rehashidx; private MyHashMap 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< (newSize); //标志开始rehash this.rehashidx = 0; } transToNewTable(); putToEntries(back,k,v); return; } putToEntries(this,k,v); } private void transToNewTable() { if (this.rehashidx tmp = this.entries[i]; if (tmp != null){ this.entries[i] = tmp.next; int index = back.index(tmp.k.hashCode()); Entry 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 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 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 k; V v; Entry next; boolean hasNext(){ return next != null; } } public static void main(String[] args) { MyHashMap 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")); }}