【java】实现自己的hashMap--基础hashcode与二叉树

来源:互联网 发布:网络宾馆 编辑:程序博客网 时间:2024/06/06 03:15

最近逛知乎,看到一篇关于红黑二叉树的文章,末尾提了一句java的hashmap用到了红黑树,突发奇想自己也写一个,尽量多地实现map的方法吧


首先,自定义自己的map接口

public interface CoolMap<K,V> {//清空coolmappublic void clear();//检查是否存在该keypublic boolean containsKey(K key);//检查是否存在该valuepublic boolean containsValue(V value);//根据key获取valuepublic V get(K key);//检查该coolmap是否为空public boolean isEmpty();//插入键值对应关系public V put(K key,V value);//插入coolMappublic void putAll(CoolMap<K,V> coolMap);//移除键值对应关系public V remove(K key);//获取当前map拥有的结点数public int size();//获取所有值的集合public Collection<V> values();//获取所有键的集合public Set<K> keySet();}

//当然如果对照map的文档,发现我少了entrySet方法,后面我再改进吧


接下来,编写coolmap的实现类,基于hashcode对比key,自然类名就是HashCoolMap

public class HashCoolMap<K, V> implements CoolMap<K, V>

然后在我目前的设计中,每个HashCoolMap可以看作是一个结点,和hashmap实现原理略有不同,那么既然是结点,就有相关的属性

private K key=null;private V value=null;private CoolMap<K, V> leftChild=null;private CoolMap<K, V> rightChild=null;

实现最基本功能,put与get方法

public V put(K key, V value) {//对所有key为null的情况不做讨论if(key==null)return null;//检测可插入当前结点if(this.key==null||this.key.hashCode()==key.hashCode()){//替换当前结点this.key=key;this.value=value;return this.value;}//根据对比hacode大小判断插入左孩子结点还是右孩子结点if(searchLeft(key)){if(leftChild==null){leftChild=new HashCoolMap<K,V>();}return leftChild.put(key, value);}else{if(rightChild==null){rightChild=new HashCoolMap<K,V>();}return rightChild.put(key, value);}}public V get(K key) {//对所有key为null的情况不做讨论if(key==null)return null;//返回当前结点的值if(this.key==null||this.key.hashCode()==key.hashCode()){return this.value;}//根据对比hashcode大小判断查找左边还是右边if(searchLeft(key)){if(leftChild==null){return null;}return leftChild.get(key);}else{if(rightChild==null){return null;}return rightChild.get(key);}}//私有方法,判断是否查找左孩子结点private boolean searchLeft(K key){return this.key.hashCode()>key.hashCode();}
编写main方法测试put与get方法
public static void main(String[] args){CoolMap<String,String> coolMap=new HashCoolMap<String,String>();System.out.println("null:"+coolMap.get("key1"));System.out.println("value1:"+coolMap.put("key1", "value1"));System.out.println("value1:"+coolMap.get("key1"));System.out.println("value2:"+coolMap.put("key1", "value2"));System.out.println("value2:"+coolMap.get("key1"));System.out.println("value2:"+coolMap.put("key2", "value2"));System.out.println("value3:"+coolMap.put("key3", "value3"));System.out.println("value4:"+coolMap.put("key4", "value4"));System.out.println("value5:"+coolMap.put("key5", "value5"));System.out.println("value6:"+coolMap.put("key6", "value6"));System.out.println("value4:"+coolMap.get("key4"));}
查看结果

其中对于key为null时的处理,我直接忽视,不过hashmap中对key为null的情况下也可以有键值对应关系

实现clear、containsKey、containsValue、isEmpty、putAll、size、values、keySet方法

public void clear() {//清空当前结点key=null;value=null;//去掉内存引用,等待java内存释放机制自动释放内存leftChild=null;rightChild=null;//虽然没什么卵用,但还是调用一下吧System.gc();}public boolean containsKey(K key) {//对所有key为null的情况不做讨论if(key==null)return false;if(this.key.hashCode()==key.hashCode()){return true;}//查找子结点if(searchLeft(key)){if(leftChild==null){return false;}return leftChild.containsKey(key);}else{if(rightChild==null){return false;}return rightChild.containsKey(key);}}public boolean containsValue(V value) {return //判断当前结点(this.value==null&&value==null)//都为null||(this.value!=null&&this.value.equals(value))//不为null//判断子结点||(this.leftChild!=null&&this.leftChild.containsValue(value))||(this.rightChild!=null&&this.rightChild.containsValue(value));}public boolean isEmpty() {//因为对key为null的情况不做考虑,因此可以将当前key是否为null作为判断依据return this.key==null;}public void putAll(CoolMap<K, V> coolMap) {Set<K> keySet=coolMap.keySet();//传入左孩子下的coolMapCoolMap<K, V> leftCoolMap=new HashCoolMap<K, V>();//传入右孩子下的coolMapCoolMap<K, V> rightCoolMap=new HashCoolMap<K, V>();for(Iterator<K> it=keySet.iterator();it.hasNext();){K key=it.next();//替换当前结点if(this.key.hashCode()==key.hashCode()){this.value=coolMap.get(key);continue;}//根据hashcode大小分配到左右孩子coolMapif(searchLeft(key)){leftCoolMap.put(key, coolMap.get(key));}else{rightCoolMap.put(key, coolMap.get(key));}}//调用子结点的putAll方法if(!leftCoolMap.isEmpty()){if(this.leftChild==null){this.leftChild=new HashCoolMap<>();}this.leftChild.putAll(leftCoolMap);}if(!rightCoolMap.isEmpty()){if(this.rightChild==null){this.rightChild=new HashCoolMap<>();}this.rightChild.putAll(rightCoolMap);}}public int size() {int currentSize=0;int leftChildSize=0;int rightChildSize=0;//当前结点数量if(this.key!=null){currentSize=1;}//左孩子结点下数量if(this.leftChild!=null){leftChildSize=this.leftChild.size();}//右孩子结点下数量if(this.rightChild!=null){rightChildSize=this.rightChild.size();}return currentSize+leftChildSize+rightChildSize;}public Collection<V> values() {Collection<V> collection=new ArrayList<V>();//判断为空if(this.isEmpty()){return collection;}//左中右if(this.leftChild!=null){collection.addAll(this.leftChild.values());}collection.add(this.value);if(this.rightChild!=null){collection.addAll(this.rightChild.values());}return collection;}public Set<K> keySet() {Set<K> set=new HashSet<K>();//添加当前结点的keyif(this.key!=null){set.add(key);}//添加子结点的keyif(this.leftChild!=null){Set<K> leftSet=this.leftChild.keySet();for(Iterator<K> it=leftSet.iterator();it.hasNext();){set.add(it.next());}}if(this.rightChild!=null){Set<K> rightSet=this.rightChild.keySet();for(Iterator<K> it=rightSet.iterator();it.hasNext();){set.add(it.next());}}return set;}

编写测试方法

public static void main(String[] args){CoolMap<String,String> coolMap=new HashCoolMap<String,String>();System.out.println("null:"+coolMap.get("key1"));System.out.println("value1:"+coolMap.put("key1", "value1"));System.out.println("value1:"+coolMap.get("key1"));System.out.println("value2:"+coolMap.put("key1", "value2"));System.out.println("value2:"+coolMap.get("key1"));System.out.println("value2:"+coolMap.put("key2", "value2"));System.out.println("value3:"+coolMap.put("key3", "value3"));System.out.println("value4:"+coolMap.put("key4", "value4"));System.out.println("value5:"+coolMap.put("key5", "value5"));System.out.println("value6:"+coolMap.put("key6", "value6"));System.out.println("value4:"+coolMap.get("key4"));System.out.println("false:"+coolMap.isEmpty());System.out.println("false:"+coolMap.containsKey("key7"));System.out.println("true:"+coolMap.containsKey("key6"));System.out.println("false:"+coolMap.containsValue("value7"));System.out.println("true:"+coolMap.containsValue("value5"));System.out.println(coolMap.values());System.out.println(coolMap.keySet());coolMap.clear();System.out.println("true:"+coolMap.isEmpty());CoolMap<String,String> coolMap1=new HashCoolMap<String,String>();coolMap1.put("k1", "v1");coolMap1.put("k2", "v2");coolMap1.put("k3", "v3");coolMap1.put("k4", "v4");CoolMap<String,String> coolMap2=new HashCoolMap<String,String>();coolMap2.put("k5", "v5");coolMap2.put("k2", "vv2");coolMap2.put("k3", "v3");coolMap2.put("k4", "v4");coolMap.putAll(coolMap1);coolMap.putAll(coolMap2);System.out.println(coolMap.keySet());System.out.println(coolMap.values());System.out.println(coolMap.size());}

结果



还有remove方法,暂时未写,溜了留了

原创粉丝点击