欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 宝鼎售后问题提交 | 后台管理


新闻资讯

MENU

软件开发知识

如果有1 昆山软件定制开发 2 3这3个Entry

点击: 次  来源:宝鼎软件 时间:2017-06-15

原文出处: 五月的仓颉

初识LinkedHashMap

上两篇文章讲了HashMap和HashMap在多线程下激发的问题,说明白,HashMap是一种非经常见、很是有用的荟萃,而且在多线程环境下利用不妥会有线程安详问题。

大大都环境下,只要不涉及线程安详问题,Map根基都可以利用HashMap,不外HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap安排的顺序,也就是无序。HashMap的这一缺点往往会带来困扰,因为有些场景,我们等候一个有序的Map。

这个时候,LinkedHashMap就闪亮登场了,它固然增加了时间和空间上的开销,可是通过维护一个运行于所有条目标双向链表,LinkedHashMap担保了元素迭代的顺序。

四个存眷点在LinkedHashMap上的谜底

假如有1  昆山软件定制开拓 2 3这3个Entry

LinkedHashMap根基数据布局

关于LinkedHashMap,先提两点:

1、LinkedHashMap可以认为是HashMap+LinkedList,即它既利用HashMap操纵数据布局,又利用LinkedList维护插入元素的先后顺序

2、LinkedHashMap的根基实现思想就是—-多态。可以说,领略多态,再去领略LinkedHashMap道剖析事半功倍;反之也是,对付LinkedHashMap道理的进修,也可以促进和加深对付多态的领略。

为什么可以这么说,首先看一下,LinkedHashMap的界说:

public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>
{
    ...
}

看到,LinkedHashMap是HashMap的子类,自然LinkedHashMap也就担任了HashMap中所有非private的要领。再看一下LinkedHashMap中自己的要领:

假如有1  昆山软件定制开拓 2 3这3个Entry

看到LinkedHashMap中并没有什么操纵数据布局的要领,也就是说LinkedHashMap操纵数据布局(好比put一个数据),和HashMap操纵数据的要领完全一样,无非就是细节上有一些的差异而已。

LinkedHashMap和HashMap的区别在于它们的根基数据布局上,看一下LinkedHashMap的根基数据布局,也就是Entry:

private static class Entry<K,V> extends HashMap.Entry<K,V> {
    // These fields comprise the doubly linked list used for iteration.
    Entry<K,V> before, after;

Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
        super(hash, key, value, next);
    }
    ...
}

列一下Entry内里有的一些属性吧:

  • K key
  • V value
  • Entry<K, V> next
  • int hash
  • Entry<K, V> before
  • Entry<K, V> after
  • 个中前面四个,也就是赤色部门是从HashMap.Entry中担任过来的;后头两个,也就是蓝色部门是LinkedHashMap独占的。不要搞错了next和before、After,next是用于维护HashMap指定table位置上毗连的Entry的顺序的,before、After是用于维护Entry插入的先后顺序的。

    照旧用图暗示一下,列一部属性罢了:

    假如有1  昆山软件定制开拓 2 3这3个Entry

    初始化LinkedHashMap

    如果有这么一段代码:

    public static void main(String[] args)
    {
        LinkedHashMap<String, String> linkedHashMap =
                new LinkedHashMap<String, String>();
        linkedHashMap.put("111", "111");
        linkedHashMap.put("222", "222");
    }

    首先是第3行~第4行,new一个LinkedHashMap出来,看一下做了什么:

    public LinkedHashMap() {
          super();
          accessOrder = false;
     }
    public HashMap() {
         this.loadFactor = DEFAULT_LOAD_FACTOR;
         threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
         table = new Entry[DEFAULT_INITIAL_CAPACITY];
         init();
    }
    void init() {
          header = new Entry<K,V>(-1, null, null, null);
          header.before = header.after = header;
     }
    /**
     * The head of the doubly linked list.
     */
    private transient Entry<K,V> header;

    这里呈现了第一个多态:init()要领。尽量init()要领界说在HashMap中,可是由于:

    1、LinkedHashMap重写了init要领

    2、实例化出来的是LinkedHashMap

    因此实际挪用的init要领是LinkedHashMap重写的init要领。假设header的地点是0×00000000,那么初始化完毕,实际上是这样的:

    假如有1  昆山软件定制开拓 2 3这3个Entry

    LinkedHashMap添加元素