`
youyu4
  • 浏览: 440149 次
社区版块
存档分类
最新评论

java -- LinkedHashMap

 
阅读更多

java -- LinkedHashMap

 

 

特点

 

  • LinkedHashMap 继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。
  • 继承自HashMap 所以依然是散列表,拥有key-value结构。
  • LinkedHashMap 键和值都可以为null。
  • 与HashMap有着同样的存储结构,但它加入了一个双向链表的头结点,将所有put到LinkedHashmap的节点一一串成了一个双向循环链表,因此它保留了节点插入的顺序,可以使节点的输出顺序与输入顺序相同。
  • 非线程安全

 

 

扩容

 

    因为是与HashMap类似的散列表,所以扩容跟HashMap也是类似的。

 

 

 

LinkedHashMap实现原理

 

       说白了,LinkedHashMap 就是 HashMap 和 LinkedList 的结合,数据的保存和HashMap一样,但额外定义了一个以head为头结点的空的双向循环链表,每次put进来Entry,除了将其保存到对哈希表中对应的位置上外,还要将其插入到双向循环链表的尾部。


      
   

 

 

 

性能问题

 

      从它的工作原理可以看出,其查询是跟HashMap一样的,同时可以根据插入顺序查询出来,但是确定也很明显,在插入、更新、删除时,因为多了个双向链表,所以效率会比较慢,并且占用更多的空间。

 

 

 

 

LinkedHashMap的构造函数

 

 

    //调用HashMap的构造方法来构造底层的数组  
    public LinkedHashMap(int initialCapacity, float loadFactor) {  
        super(initialCapacity, loadFactor);  
        accessOrder = false;    //链表中的元素默认按照插入顺序排序  
    }  
  
    //加载因子取默认的0.75f  
    public LinkedHashMap(int initialCapacity) {  
        super(initialCapacity);  
        accessOrder = false;  
    }  
  
    //加载因子取默认的0.75f,容量取默认的16  
    public LinkedHashMap() {  
        super();  
        accessOrder = false;  
    }  
  
    //含有子Map的构造方法,同样调用HashMap的对应的构造方法  
    public LinkedHashMap(Map<? extends K, ? extends V> m) {  
        super(m);  
        accessOrder = false;  
    }  
  
    //该构造方法可以指定链表中的元素排序的规则  
    public LinkedHashMap(int initialCapacity,float loadFactor,boolean accessOrder) {  
        super(initialCapacity, loadFactor);  
        this.accessOrder = accessOrder;  
    } 

 

 

注意:accessOrder标志位,当它false时,表示双向链表中的元素按照Entry插入LinkedHashMap到中的先后顺序排序

 

      注意构造方法,前四个构造方法都将accessOrder设为false,说明默认是按照插入顺序排序的,而第五个构造方法可以自定义传入的accessOrder的值,因此可以指定双向循环链表中元素的排序规则,一般要用LinkedHashMap实现LRU算法,就要用该构造方法,将accessOrder置为true。

 

 

 

 

put方法和get方法

 

      LinkedHashMap在定义put和get方法的时候,重写了HashMap的put方法和get方法,这样就可以在期间加入双向链表的操作。

 

// 将“key-value”添加到HashMap中      
public V put(K key, V value) {      
    // 若“key为null”,则将该键值对添加到table[0]中。      
    if (key == null)      
        return putForNullKey(value);      
    // 若“key不为null”,则计算该key的哈希值,然后将其添加到该哈希值对应的链表中。      
    int hash = hash(key.hashCode());      
    int i = indexFor(hash, table.length);      
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {      
        Object k;      
        // 若“该key”对应的键值对已经存在,则用新的value取代旧的value。然后退出!      
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {      
            V oldValue = e.value;      
            e.value = value;      
            e.recordAccess(this);      
            return oldValue;      
        }      
    }      
  
    // 若“该key”对应的键值对不存在,则将“key-value”添加到table中      
    modCount++;    
    //将key-value添加到table[i]处    
    addEntry(hash, key, value, i);      
    return null;      
}      

 

//覆写HashMap中的get方法,通过getEntry方法获取Entry对象。  
//注意这里的recordAccess方法,  
//如果链表中元素的排序规则是按照插入的先后顺序排序的话,该方法什么也不做,  
//如果链表中元素的排序规则是按照访问的先后顺序排序的话,则将e移到链表的末尾处。  
   public V get(Object key) {  
       Entry<K,V> e = (Entry<K,V>)getEntry(key);  
       if (e == null)  
           return null;  
       e.recordAccess(this);  
       return e.value;  
   } 

 

 

 

 

LinkedHashMap的API



 

 

 

 

LRU算法

 

      首先,当accessOrder为true时,才会开启按访问顺序排序的模式,才能用来实现LRU算法。我们可以看到,无论是put方法还是get方法,都会导致目标Entry成为最近访问的Entry,因此便把该Entry加入到了双向链表的末尾(get方法通过调用recordAccess方法来实现,put方法在覆盖已有key的情况下,也是通过调用recordAccess方法来实现,在插入新的Entry时,则是通过createEntry中的addBefore方法来实现),这样便把最近使用了的Entry放入到了双向链表的后面,多次操作后,双向链表前面的Entry便是最近没有使用的,这样当节点个数满的时候,删除的最前面的Entry(head后面的那个Entry)便是最近最少使用的Entry。

 

  • 大小: 58.3 KB
  • 大小: 99.3 KB
分享到:
评论

相关推荐

    java集合-LinkedHashMap的使用

    LinkedHashMap是Java中的一种特殊类型的HashMap,它保留了插入顺序,即按照元素插入的先后顺序进行排序

    Java-Interview-超全集合github上评分最高的jiva面试题

    - **Map**:HashMap、TreeMap、LinkedHashMap的工作机制,特别是HashMap的线程不安全问题及其解决方案。 - **集合接口与实现**:了解Collection、Iterable、List、Set、Map等接口,以及它们各自的实现类。 3. **...

    计算机后端-Java-Java核心基础-第25章 集合02 13. LinkedHashMap的底层实现.avi

    计算机后端-Java-Java核心基础-第25章 集合02 12. HashMap在JDK8中的源码分析.avi

    java第18章java-chapter18.rar

    第18章可能深入分析这些接口和类的特性和使用场景,比如ArrayList、LinkedList、HashSet、TreeSet、HashMap、LinkedHashMap等。 7. **设计模式**:设计模式是解决常见编程问题的最佳实践。这一章可能会介绍一些常见...

    java-collections-framework1016

    ### Java Collections Framework 1016 #### 一、教程概览 本教程由developerWorks提供,旨在深入探讨Java Collections Framework。它不仅适用于初学者,也适合具有一定经验的开发人员。教程从简单的编程示例开始,...

    JavaLinkedHashMap源码解析Java开发Ja

    Java LinkedHashMap 是一个根据插入顺序或者访问顺序来维护元素顺序的哈希表与链表相结合的数据结构。在 Java 集合框架中,它继承自 HashMap 类,并实现了 Map 接口。LinkedHashMap 的特点在于,它不仅仅是一个哈希...

    5-java-QA.rar_Quick

    - HashMap, TreeMap, LinkedHashMap:键值对存储,用于高效查找。 5. **多线程** - Thread类:表示程序执行的线程。 - Runnable接口:实现`run()`方法,可以被线程执行。 - synchronized关键字:保证线程安全,...

    JAVA-POI通用工具类.doc

    【JAVA-POI通用工具类】是用于处理Excel数据导入导出的一个实用工具包,主要基于Apache POI库。Apache POI是一个流行的API,它允许Java应用程序读取、写入和修改Microsoft Office格式的文件,包括Excel。在这个文档...

    java-all.pdf

    - **LinkedHashMap**:保持插入顺序的哈希映射。 - **Hashtable**:线程安全的映射。 - **IdentityHashMap**:基于对象身份而非哈希码的映射。 - **WeakHashMap**:允许键被垃圾回收的映射。 - **Collections**...

    java-遍历map

    `Map`的主要实现类有`HashMap`、`TreeMap`、`LinkedHashMap`、`ConcurrentHashMap`等,它们各自具有不同的特性,如`HashMap`提供了快速的随机访问,而`TreeMap`则保证了键的自然排序。 ### 二、使用keySet遍历Map ...

    java-datestruct.rar_数据结构

    8. **Map**:Map接口存储键值对,Java的HashMap、TreeMap和LinkedHashMap等实现了Map接口。 9. **哈希表(HashMap)**:哈希表提供快速的查找,通过计算元素的哈希码来确定其存储位置。HashMap是Java中最常用的哈希...

    java-collection-all-in-one.pdf

    LinkedHashMap是HashMap的一个子类,它维护着一条双向链表记录插入顺序或访问顺序,这样可以按照插入或访问的顺序来迭代元素。removeEldestEntry方法用于定义删除最老元素的条件,可用于实现缓存机制。 EnumMap是一...

    Java-collection-frame.rar_Java集合框架

    LinkedHashMap则同时保持了插入顺序或访问顺序。 4. Collection接口:Collection是List和Set的父接口,提供了基础的集合操作,如add()、remove()和size()。ArrayList、LinkedList、HashSet和TreeSet都直接或间接...

    java中HashMap,LinkedHashMap,TreeMap,HashTable的区别

    ### Java中HashMap, LinkedHashMap, TreeMap,HashTable的区别 在Java编程语言中,`Map`接口是集合框架中的一个重要组成部分,用于存储键值对。本文将详细分析四种常用的`Map`实现类:`HashMap`, `LinkedHashMap`, ...

    Java-实用程序设计第章-容器类(共52张PPT).pptx

    Java容器类是Java集合框架的重要组成部分,主要用于存储和管理对象。在Java中,容器被分为两大类:Collection和Map。 1. **Collection接口**:Collection是所有单值容器的父接口,它定义了存储单一对象的基本操作。...

    day12 java

    根据提供的文件信息,我们可以深入探讨Java中集合框架的相关知识点,特别是集合的概念、与数组的区别、集合的分类及其应用场景等。 ### 集合的基本概念 集合(Collection)在Java中是一种容器,用来存储对象。与...

    JAVA-SE入门学习——第八讲集合

    以上内容涵盖了Java集合框架的基础知识,包括Collection接口、Set接口、List接口、Map接口的理解和使用,以及泛型、集合与数组的转换、集合的遍历和复制等重要概念。在实际开发中,掌握这些知识对于编写高效、安全的...

    java-leetcode面试题解哈希表第1603题设计停车系统-题解.zip

    在Java中,我们可以使用哈希表(如HashMap或LinkedHashMap)来实现这个系统。哈希表的键(Key)可以表示车位类型,值(Value)可以是车位数量的计数器。例如,键可能是"大型车",值则表示当前大型车的空闲车位数。...

Global site tag (gtag.js) - Google Analytics