自己动手实现集合框架类(四)之LinkedHashMap

linkedHashMap跟和HashMap结构,只是加了两个属性,也就是为了记录前一个插入的元素(before)和记录后一个插入的元素(next)。
LinkedHashMap定义的Entry结构如下:

这里写图片描述

next和after可能会指向同一个Entry,next也可能指向null。

整个结构如下:(图片来http://www.cnblogs.com/chenpi/p/5294077.html
这里写图片描述

从上图,我们可以看到,LinkedHashMap跟HashMap插入元素的原理相同,通过hash值寻找插入到数组的位置,只是每次插入的元素需要维护其前一个节点(before)和后一个节点(after)的指针。

LinkedHashMap实现:

package com.java.myutil;
/**
 * 继承我们已经实现的HashMap方法
 */
public class LinkedHashMap extends HashMap implements Map {
    //双向循环链表的头节点
    private Entry head;
    int size=0;
    //初始化时,循环链表的前一个和后一个节点都是自身
    public LinkedHashMap() {
        head=new Entry(-1, null, null, null);
        head.before=head.after=head;
    }
    static class Entry extends HashMap.Node{
        Entry before;//指向前一个Entry,
        Entry after;//指向后一个Entry,

        Entry(int hash, Object key, Object value, Node next) {
            super(hash, key, value, next);
        }
        //往双向循环链表里天添加节点,都是在头结点前加入
        public void addBefore(Entry head) {
                this.after=head;
                this.before=head.before;

                this.after.before=this;
                this.before.after=this;

        }

    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size==0;
    }

    public Object get(Object key) {

        int hash = (key == null) ? 0 : hash(key);
        int i= indexFor(hash, table.length);
        for (Node e = table[i];e != null;e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
                return e.getValue();
        }
        return null;

    }
   /**
    * LinkedHashMap继承自HashMap,put(),方法,使用继承的HashMap的put方法,但是重写了put方法中的addEntry方法
    */
    @Override
    public void addEntry(Object key, Object value, int hashValue, int i) {
          //在这里也可以通过size的大小决定是否扩展数组大小
          /*
           * 省略...可看hashmap的扩展
           **/


        //在继承的HashMap的put方法中,到这一步,已经判断如下:如果i位置没有数据,或者i位置有数据,但是key是新的key,则新增节点
          HashMap.Node old=table[i];
          Entry entry=new Entry(hashValue, key, value, old);
          table[i]=entry;
          //将新增的entry放到双向循环列表的头部
          entry.addBefore(head);
          size++;

    }
    public static void main(String[] args) {
        LinkedHashMap linkedHashMap =new LinkedHashMap();
        linkedHashMap.put("aaa", "111");
        linkedHashMap.put("bbb", "222");
        linkedHashMap.put("ccc", "333");

        System.out.println(linkedHashMap.get("aaa"));

    }
}

猜你喜欢

转载自blog.csdn.net/u010248330/article/details/75115531