与javaAPI中的实现方式思想相通实现细节不同,不过更容易理解!
话不多说,直接上代码!代码中有关键部分的解释:
接口Entry<K,V>
public interface Entry<K,V> { K getKey(); V getValue(); V setValue(V value); }
hashMap实现类,只要实现了put和get方法
/** * 根据hashmap底层实现,自己简单的手撸一个hashmap * * @author wolf * @create 2018-06-06 14:32 */ public class wolfHashMap<K, V> { //default size of hashMap;桶的默认大小 static int DEFAULTSIZE = 16; //hashMap's factor to resize 加载影子,当当前的hashmap存储的元素个数大于DEFAULTSIZE*FACTOR,就需要rehash和resize static double FACTOR = 0.75; //define length of elements in hashMap int size_eles = 0; //define arrays of story Node<K, V>[] node; //define the node of store in hashMap class Node<K, V> implements Entry<K, V> { private K key; private V value; 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 key; } @Override public V getValue() { return value; } @Override public V setValue(V value) { V result = this.value; this.value = value; return result; } } //构造函数 public wolfHashMap() { this.node = new Node[DEFAULTSIZE]; } public wolfHashMap(int size, double factor) { this.DEFAULTSIZE = size; this.FACTOR = factor; this.node = new Node[DEFAULTSIZE]; } //put方法的实现 public V put(K key, V value) { V result = null; //添加之前看是否需要扩容,扩容的时候需要resize和rehash if (size_eles >= DEFAULTSIZE * FACTOR) resize(size_eles); int index = hashCode(key); //在添加之前还要判断添加的key是否已经存在于hash表中 Node temp = node[index]; while (temp != null) {//在这里处理相同key情况。key相同时,将value替换成原来的value,并将旧的value返回 if (temp.getKey() == key) { result = (V) temp.getValue(); temp.value = value; return result; } temp = temp.next; } //能到这里来说明新添加的节点与原来存储的数据都不冲突 node[index] = new Node<>(key, value, null); node[index].next = temp; size_eles++; return result; } //get方法 public V get(K key) { int index = hashCode(key); Node cur = node[index]; while (cur != null) { if (cur.getKey() == key) return (V) cur.getValue(); cur = cur.next; } //找不到返回null return null; } //获取存储元素的个数 public int size() { return size_eles; } //扩容方法,每次在现有的容量上扩大2倍 private void resize(int size) { Node<K, V>[] newNode = new Node[DEFAULTSIZE * 2]; DEFAULTSIZE = DEFAULTSIZE * 2; //将原来hashmap存储的数据(Node[])从新存储到newNode中 for (int i = 0; i < node.length; i++) {//遍历诶个数组节点 Node temp = node[i]; while (temp != null) {//由于一个节点后可能存在其他链接的节点,所以需要进一步遍历每个节点 int index = hashCode((K) temp.getKey()); Node before = newNode[index]; newNode[index] = temp; newNode[index].next = before; temp = temp.next; } } node = newNode; } //hash算法,简单除留余法 private int hashCode(K key) { return key.hashCode() % DEFAULTSIZE; } }
测试类:
/** * @author wolf * @create 2018-06-06 15:52 */ public class Test { public static void main(String[] args) { wolfHashMap<String,String> wolfHashMap = new wolfHashMap<>(); wolfHashMap.put("wolf", "haha"); wolfHashMap.put("wolf", "haha"); wolfHashMap.put("wolf", "haha"); wolfHashMap.put("wolf", "haha"); System.out.println(wolfHashMap.size()); wolfHashMap.put("wolf1", "haha"); System.out.println(wolfHashMap.size()); System.out.println(wolfHashMap.get("1")); } }