手写HashMap,实现put,get以及扩容

来源:互联网 发布:java实现扫码支付 编辑:程序博客网 时间:2024/05/21 10:17

很晚了不多说了,直接贴代码,看完就会了解HashMap是如何实现数组+链表存储的,希望能给大家带来帮助,如果有疑问和纠正,请留言,第一时间回复


public class MyHashMap<K,V> {public Node<K,V>[] table;private static final int DEFAULT_INITAIL_CAPACITY = 1<<4;//负载因子private static final float DEFAULT_LOAD_FECTOR = 0.75f;//非null的个数private static int size;private static int theshold;static class Node<K,V>{private int hash;private K key;private V value;private Node<K,V> next;public Node(int hash, K key, V value, Node<K, V> next) {super();this.hash = hash;this.key = key;this.value = value;this.next = next;}public int getHash() {return hash;}public void setHash(int hash) {this.hash = hash;}public K getKey() {return key;}public void setKey(K key) {this.key = key;}public V getValue() {return value;}public void setValue(V value) {this.value = value;}public Node<K, V> getNext() {return next;}public void setNext(Node<K, V> next) {this.next = next;}@Overridepublic String toString() {StringBuffer stringBuffer = new StringBuffer();stringBuffer.append(key+"("+hash+")");stringBuffer.append("=");stringBuffer.append(value);stringBuffer.append(",");if(null != next){stringBuffer.append(next.toString());}return stringBuffer.toString();}}/** * 添加元素 * @param key * @param value */public void put(K key,V value){//获取hashint hash = Objects.hashCode(key);//指定数组长度,初始化数组int length = DEFAULT_INITAIL_CAPACITY;if(table == null){theshold = (int)(DEFAULT_INITAIL_CAPACITY * DEFAULT_LOAD_FECTOR);table = new Node[length];}//根据hashCode取模算出数组下标//int i = hash % length;// &运算代替取模int i = hash & (length -1);//0000-1111 0-15//判断table[i]是否存在if(null == table[i]){table[i] = new Node<K, V>(hash,key,value,null);}else{Node<K,V> node = table[i];//判断table[i].key是否等于传入的keyif((node.hash == hash) && (node.key == key ||((key !=null) && node.key.equals(key)))){node.value = value;}else{for (int count = 0;; count++) {if(null == node.next){node.next = new Node<K, V>(hash,key,value,null);break;}//判断nextif((node.next.hash ==hash) && (node.next.key == key || (key != null && node.next.key.equals(key)))){node.next.value = value;break;}node = node.next;}}}size++;if(size >= theshold){resize();}}//扩容方法private void resize(){//大小翻倍int newCapacity = table.length << 1;theshold = (int)(newCapacity * DEFAULT_LOAD_FECTOR);Node<K,V>[] newTable = new Node[newCapacity];//转移数据for (Node<K, V> oldNode : table) {if(null == oldNode){continue;}for (int count = 0;; count++) {if(oldNode == null){break;}Node<K,V> next = oldNode.next;//新table的下标int i = oldNode.hash & (newCapacity -1);oldNode.next = newTable[i];newTable[i] = oldNode;oldNode = next;}}//替换tabletable = newTable;}/** * 获取元素 * @param key * @return */public V get(K key){//获取key的hashint hash = Objects.hashCode(key);//判断tableif(table == null || table.length <= 0){return null;}//根据hashCode取模算出数组下标//int i = hash % length;// &运算代替取模int i = hash & (table.length -1);//0000-1111 0-15Node<K,V> node = table[i];if(node == null){return null;}//按断key是否相等if((node.hash == hash) && ((node.key == key) || (key != null && node.key.equals(key)))){return node.value;}else{for (int count = 0;; count++) {if(node.next != null){if((node.next.hash == hash) && ((node.next.key == key) || (key != null && node.next.key.equals(key)))){return node.next.value;}node = node.next;}}}}@Overridepublic String toString() {StringBuffer stringBuffer = new StringBuffer("{");for (Node<K, V> node : table) {if( null == node){continue;}stringBuffer.append(node.toString());}stringBuffer.append("}");return stringBuffer.toString();}}