hashmap元素插入是无序的。为了允许遍历顺序和插入顺序保持一致,我们可以使用linkedhashmap。它维护一个两条链接列表以存储元素的顺序。它可以通过登录器属性控件控制插入的顺序。
LinkedHashmap类层次关系图:
LinkedHashMap从Hashmap继承,大多数方法直接使用hashmap。然后检查成员变量:
头部和尾巴使用瞬态修改,因为在介绍哈希姆普源代码的原理时,对它们进行了详细分析。
LinkedHashMap从Hashmap继承,因此内部存储的数据与Hashmap相同。链接列表阵列的结构存储数据(红树和黑树)。与linkedhashmap和hashmap相比,使用额外的两道链接列表来存储节点的顺序。此两条路链接列表的类型是linkedhashmap.entry:entry:entry:entry:entry:entry:entry:entry:
linkedhashmap.entry类 - 级别关系图:
linkedhashmap.entry从哈希玛的节点类中继承,该类别添加了以前和来世属性以维护以前和后继节点以形成一个两道链接列表。
LinkedHashmap的构造函数实际上并不特别,即调用父类构造函数的初始化的过程,但是LinkedHashmap的登录属性的操作更加初始化:
在分析LinkedHashmap方法的实现之前,我们可以通过一个示例体验LinkedHashmap的特征:
可以看出,元素的输出顺序是我们插入的顺序。
将访问者属性更改为true:
可以看出,开始时的输出。当我们通过get方法访问密钥的键值时也就是说,最近的访问将移至两条路列表的末尾的元素。所谓的“访问”不仅是GET方法。符合“访问”一词的操作包括put,putifabsnt,get getRedefault,computeifabsent,computeifprence和Merge。
下面我们可以清楚地知道LinkedHashmap如何通过分析方法源代码来控制元素的顺序。
LinkedHashMap没有重写PUT(K键,V值)方法,并直接使用了HashMap的PUT(K键,V值)方法。由于linkedhashmap不会重写put(k键,值),因此它如何维护内部两条路链接列表中的元素顺序?我们可以找到put的源代码的原因(k键,v值)方法(因为PUT(K键,V值)源代码已根据Java-Hashmap的基础实现的实现原则进行了分析,因此我们仅与下面的LinkedHashmap函数有关。代码上的ADD注释):
NewNode方法用于创建一个链接的列表节点。LinkedHashMap重写了NewNode方法:
可以看出,对于linkedhashmap实例,在put操作中创建的节点类型是linkedhashmap.entry。除了将数据插入哈希姆普之外,它还将数据插入了linkedhashmap的两个链接列表中。
如果将数据插入红色和黑色树结构中,则将PUT将Puttreeval方法调用到红色和黑色树中,而Puttreeval方法通过NewTreenode方法创建树节点。LinkedHashMap重写新treenode方法:新treenode方法:
节点类型是及时的,因此该类型在哪里定义?实际上,treenode是在hashmap中定义的,请检查其源代码:
treenode从linkedhashmap.entry继承:
因此,treenode还包含 - 之后的属性之前和之后。即使插入的节点类型是treenode,您仍然可以使用linkedhashmap两道链列表来维护节点的顺序。
在PUT方法中,如果已经存在插入的密钥,将执行下午的操作。此方法是hashmap中的空方法:
名称所暗示的方法之后,该方法是在访问节点时执行某些操作。linkedHashMap重写此方法:
因此,当访问器正确时,调用linkedhashmap的put方法并插入相同键值的键值对,键值将移至尾巴:
在PUT方法的末尾,顾名思义,该方法也被调用,该方法用于插入节点以执行某些操作。此方法也是哈希图中的一种空置方法:
LinkedHashMap重写此方法:
基于此功能,我们可以通过继承LinkedHashmap方法来实现LRU,然后在下面实现它来重写RemoteLedestry方法。
您可以询问,删除哈希图表中的节点。因此,不是用来维护节点顺序的两个链接列表,不应该删除头节点吗?为什么上面的代码没有看到操作的此部分?实际上,当您检查源代码时在Removenode方法中,您可以看到操作的这一部分:
顾名思义,下午登录方法用于节点删除并执行以下操作。该方法在hashmap中为空:
LinkedHashMap重写此方法:
通过此方法,我们从linkedhashmap的两个链接列表中删除了头节点。
实际上,通过PUT方法,我们弄清楚了内部链接hashmap如何在两个路线链接列表中维护的钥匙值。但是,为了使文章Fuller,分析了以下方法源代码。
linkedhashmap重写哈希玛普的获取方法:
linkedhashmap不会重写删除方法,请检查hashmap的删除方法:
由于linkedhashmap在两个路线链接列表中以维护钥匙值,因此我们可以猜测,遍历LinkedHashmap实际上正在遍历linkedhashmap维护的两条路链接列表:
查看LinkedHashmap类入门集方法的实现:
以上代码符合我们的猜测。
LRU(最近使用的最少使用)是指最近的最低用途。这是一种缓存消除算法。
我们知道,LinkedHashMap中的RemoveLestEntry方法已固定为false,并且不会执行元素的删除,因此我们可以通过继承LinkedHashMap并重写RemoverEmentEstertry方法来重写LRU。
如果我们现在有以下需求:
使用linkedhashmap实现缓存。缓存最多只能存储5个元素。当元素的数量超过5时,删除(消除)数据最近使用的数据最少使用,仅保存热数据。
创建一个新的lrucache类,并继承LinkedHashmap:
您会看到最早的插入1 = A已删除。
通过LinkedHashmap实现LRU很普遍。例如,记录框架的lrumessagecache: