Java Custom HashMap
来源:互联网 发布:淘宝开店用什么软件好 编辑:程序博客网 时间:2024/04/29 01:15
我们都知道hashmap的数据结构是基于数组+链表,现在自己就仿照JDK里面的HashMpa来实现一个简易的自己的hashmap。主要考虑以下功能点:
- put:把值放入到Map中储存起来
- get:从Map中获取一个键值的值
- size:获取Map的储存数据的个数
1、定义接口 – MyMap
定义一个MyMap接口,用于实现简单的Map接口
MyMap.java
public interface MyMap<K, V> { V put(K key, V value); V get(K key); int size(); interface Entry<K, V>{ K getKey(); V getValue(); }}
2、实现接口 – MyHashMap
实现自定义的MyHashMap.
MyHashMap.java
public class MyHashMap<K, V> implements MyMap<K, V> { private final static int DEFAULT_INIT_CAPACITY = 16; private final static float DEFAULT_LOAD_FACTOR = 0.75F; private int capacity = DEFAULT_INIT_CAPACITY; private float loadFactor = DEFAULT_LOAD_FACTOR; private Node<K, V>[] table = null; private int size = 0; public MyHashMap(int capacity, float loadFactor){ if(capacity < 0){ throw new RuntimeException("capacity can less than 0, is " + capacity); } if(loadFactor <= 0 || loadFactor >1){ throw new RuntimeException("loadFactor error, is " + loadFactor); } this.capacity = capacity; this.loadFactor = loadFactor; table = new Node[this.capacity]; } public MyHashMap(){ this(DEFAULT_INIT_CAPACITY, DEFAULT_LOAD_FACTOR); } public V put(K key, V value) { if(size > capacity * loadFactor){ up2Size(); } int index = getIndex(key); Node<K, V> node = table[index]; size++; if(node == null){ table[index] = newNode(key, value, null); } else { table[index] = newNode(key, value, node); } return value; } public V get(K key) { int index = getIndex(key); Node<K, V> node = table[index]; if(node == null){ return null; } return findValueByEqualKey(key, node); } public int size() { return size; } private Node<K, V> newNode(K key, V value, Node<K, V> next) { return new Node<K, V>(key, value, next); } /** * 扩容 */ private void up2Size() { Node<K, V>[] newTable = new Node[capacity * 2]; againHash(newTable); } /** * 重新hash * @param newTable */ private void againHash(Node<K, V>[] newTable) { List<Node<K, V>> nodes = new ArrayList<Node<K, V>>(); for(Node<K, V> node : table){ if(node == null){ continue; } findNodeByNext(node, nodes); } if(nodes.size() > 0){ // 重要设置Map的属性 capacity = capacity * 2; size = 0; table = newTable; for(Node<K, V> node : nodes){ if(node.next != null){ // 因为链表的next已经添加到List容器了,需要置null. node.next = null; } put(node.getKey(), node.getValue()); } } } /** * 获取链表下的所有节点 */ private void findNodeByNext(Node<K, V> node, List<Node<K, V>> nodes) { if(node != null && node.next != null){ nodes.add(node); findNodeByNext(node.next, nodes); } else { nodes.add(node); } } /** * 获取hash */ private int getIndex(K key) { int hashCode = key.hashCode(); int index = hashCode & capacity - 1; return index < 0 ? -index : index; } /** * 遍历节点下面的链表 */ private V findValueByEqualKey(K key, Node<K, V> node) { if(key == node.getKey() || key.equals(node.getKey())){ return node.getValue(); } else { if(node.next != null){ return findValueByEqualKey(key, node.next); } } return null; } class Node<K,V> implements Entry<K, V>{ private K key; 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; } public K getKey() { return key; } public V getValue() { return value; } @Override public String toString() { return "Node{" + "key=" + key + ", value=" + value + '}'; } }}
3、测试
写一个测试类,用于检测实现接口的正确性。
public class Test { public static void main(String[] args) { MyMap<String, String> map = new MyHashMap<String, String>(); for(int i = 0; i < 1000; i++){ map.put("key" + i, "value" + i); } System.out.println("测试是否每个值都放入到Map中,而且扩容的时候有没有丢掉数据"); for(int i = 0; i < 1000; i++){ String value = map.get("key" + i); System.out.println("key : key" + i + ", value : " + value); } System.out.println("map里面数据的个数为 : " + map.size()); }}
上面的图片只是截取了验证后面的结果,前面的value都是有值的。之前出现了错误,就是在扩容的时候没有把所有的元素添加进去。导致里面有些key的值是null.
4、总结
虽然上面的代码基本上实现了Map的功能,但是与JDK里面的HashMap比较还是存在很多不足点。归纳如下:
- 没有考虑key值为空的情况。
- 没有考虑用户使用有参构造器传值不是2的指数次幂
- 对于同一节点的链表过长没有考虑性能优化
So what.这只是一个Map的简易实现。
0 0
- Java Custom HashMap
- java custom classloader
- java hashMap
- Java HashMap
- java---hashmap
- java hashmap
- Java HashMap
- JAVA-HASHMAP
- java Hashmap
- java HashMap
- Java HashMap
- java HashMap
- Java - HashMap
- Java hashMap
- Java HashMap
- java-hashmap
- Java HashMap
- 【java】HashMap
- PREV-34矩阵翻硬币 (高精度开方,相乘)
- 比赛排名
- 子串计算
- log4j的文件配置
- matlab例题及demo分析
- Java Custom HashMap
- 广播:开机自启播放音乐
- mysql的db.properties文件
- mybatis的映射文件的头格式
- TCP原理与应用详解
- 506. Relative Ranks
- 子串计算
- Ubuntu16.04 设置mysql服务器字符集命令
- 数据库存储图片解决方案