package io.renren; public class ExtHashMap<K,V> implements ExtMap<K,V>{ Node<K,V>[] table = null; int size; //负载因子,扩容的时候才会用到,负载因子越低,冲突越小 float DEFAULT_LOAD_FACTOR = 0.75f; //默认初始化容量大小 static int DEFAULT_INIITAL_CAPACITY = 16; @Override public V put(K key, V value) { //1.判断table数组长度是否为空,如果为空就初始化 if(table == null){ table = new Node[DEFAULT_INIITAL_CAPACITY]; } //2.判断数组是否需要扩容 //3.计算hash指定位置 int index = getIndex(key,DEFAULT_INIITAL_CAPACITY); Node<K, V> kvNode = table[index]; Node<K, V> flagNode = null; //2.hashMap 扩容机制 为什么要扩容? 扩容后有什么影响? hashMap中是从什么时候开始扩容的 //不扩容的话会导致hashMap底层链表越来越多,导致查询变慢。扩容后,index会发生变化。 //hashMap会在 size>=数组长度*负载因子 if(size>=(DEFAULT_INIITAL_CAPACITY*DEFAULT_LOAD_FACTOR)){ resize(); } if(kvNode == null){ kvNode = new Node<K,V>(key,value,null); size++; }else { //已经发生hash冲突问题的key 直接添加(冲突node)到前面了 不是往后面加 //把老的node 添加到新的node节点的 next上面 flagNode = kvNode; while (flagNode !=null){ if(flagNode.getKey().equals(key) || flagNode.getKey() == key){ //kvNode.value = value; kvNode = flagNode; return kvNode.setValue(value); } flagNode =flagNode.next; } kvNode = new Node<K,V>(key,value,kvNode); size++; } table[index] = kvNode; return null; } private void resize(){ // 1.生成新的table 是之前的两倍的大小 Node<K,V>[] newTable = new Node[DEFAULT_INIITAL_CAPACITY << 1]; // 2.重新计算index索引,存放在新的table里面 for (int i = 0; i < table.length; i++) { Node<K, V> oldNode = table[i]; while(oldNode !=null){ table[i] =null; //方便垃圾回收机制回收 //存放在之前的table 原来的node key K oldK = oldNode.key; //重新计算index int index = getIndex(oldK, newTable.length); //扩容后的 发生冲撞的链表数组 相反顺序存放 Node<K, V> nextNode = oldNode.next; oldNode.next = newTable[index]; //赋值 newTable[index] = oldNode; oldNode = nextNode; } } // 3.将新的table赋值给老的table table=newTable; DEFAULT_INIITAL_CAPACITY = table.length; } private int getIndex(K k,int length) { int hashCode = k.hashCode(); int index = hashCode % (length - 1); return 4; } @Override public V get(K k) { Node<K, V> node = table[getIndex(k,DEFAULT_INIITAL_CAPACITY)]; while(node != null){ if(node.getKey().equals(k)||node.getKey() == k){ return node.value; } node=node.next; } return null; } @Override public int size() { return 0; } //定义节点 class Node<K,V> implements Entry<K,V>{ //存放map 集合key private K key; //存放map 集合Value private V value; //定义下一耳光节点 private Node<K,V> next; public Node(K key, V value, Node<K, V> next) { this.key = key; this.value = value; this.next = next; } @Override public K getKey() { return this.key; } @Override public V getValue() { return this.value; } @Override public V setValue(V value) { V oldVal = this.value; this.value=value; return oldVal; } } void print(){ for (int i = 0; i < table.length; i++) { Node<K, V> node = table[i]; System.out.print("下标位置[" + i + "]"); while (node != null) { System.out.print("[ key:" + node.getKey() + ",value:" + node.getValue() + "]"); node = node.next; } System.out.println(); } } }
参考HashMap底层源码手撸hashMap
最新推荐文章于 2021-02-18 18:50:38 发布