首页 > 编程知识 正文

linkedhashmap原理,linkedhashmap循环

时间:2023-05-06 03:05:00 阅读:55643 作者:1170

本文详细介绍了链接的hashmap的内部,这是Java Map接口的实现类。 这是HashMap的子类,继承父类的核心代码。 因此,读者应该首先了解HashMap的工作原理。

LinkedHashMap和HashMap *LinkedHashMap *在大多数方面与HashMap相似,但LinkedHashMap用于根据hash表和链表结构增强HashMap。 在下面,除了缺省的16个大小的数组外,还保留了链接所有项的双向链表。

为了保持元素的顺序,链接的HashMap修改了HashMap类的Map.Entry类,并添加了before和after指针对象。 源代码如下:

/* * hashmap.nodesubclassfornormallinkedhashmapentries.*/staticclassentryk,V extends HashMap.NodeK,V { EntryK,v } }我们发现entry类很容易添加两个指针以连接到链表,并使用entry类实现了HashMap。

我在看构造函数。 默认定义迭代顺序,默认遵循插入顺序。

publiclinkedhashmap (intialcapacity,浮动加载因子) super (initial capacity,加载因子); 访问顺序=false; }“插入顺序”(Insertion-Order )以下是插入顺序的实例。

@ testpublicvoidgivenlinkedhashmap _ whengetsorderedkeyset _ then correct ({ linkedhashmapinteger,字符串图=newlinkedhed map.put(2,null ); map.put(3,null ); map.put(4,null; map.put(5,null; SetInteger keys=map.keySet (; integer [ ] arr=keys.to array (new integer [0]; for(intI=0; i arr.length; I ) {assertequals(newinteger(I1 ),arr[i] ); }上述代码插入五个实体,获取其密钥集,最后重复验证密钥顺序。 LinkHashMap可以保证密钥顺序是插入顺序,HashMap不能保证密钥顺序。

特性在一些场景中非常有用。 如果需要根据客户端的优先级返回对API的调用,则LinkHashMap可以轻松应对。

注:将键重新插入地图不会影响插入顺序。

在“访问顺序”(Access-Order )的上一部分中,构造函数包含三个参数:初始容量、负载系数和排序策略,默认情况下设置为插入顺序。 也可以设置为访问顺序。 此机制可确保元素按上次访问顺序、最近访问顺序、最近访问顺序和最近访问顺序重复的元素顺序。

@ testpublicvoidgivenlinkedhashmap _ whenaccessorderworks _ then correct ((linkedhashmapinteger,string map=newlinkedhamam map.put(2,null ); map.put(3,null ); map.put(4,null; map.put(5,null; SetInteger keys=map.keySet (; 资产质量(' [ 1,2,3,4,5 ] ',keys.toString ) ); map.get(4; 资产质量(' [ 1,2,3,5,4 ] ',keys.toString ) ); map.get(1; 资产质量(' [ 2,3,5,4,1 ] ',keys.toString ) ); map.get(3; 资产质量(' [ 2,5,4,1,3 ] ',keys.toString ) ); }该策略可以轻松实现分布式(LRU )缓存算法。 如果访问特定于map的密钥,则在迭代期间密钥将显示在最后。 在上面的例子中,显然

然迭代LinkHashMap不会影响顺序,仅仅显示的访问操作会影响。

LinkHashMap还提供了维护map条目为固定大小的机制,对已经条目数量为最大时,当插入新的元素则最老的元素会被删除。

我们可以重写removeEldestEntry方法,以强制该策略自动删除过时的条目。下面示例定义MyLinkedHashMap类,重写

removeEldestEntry方法:

public class MyLinkedHashMap<K, V> extends LinkedHashMap<K, V> { private static final int MAX_ENTRIES = 5; public MyLinkedHashMap( int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor, accessOrder); } @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > MAX_ENTRIES; }}

当条目超过最大值时,新条目被插入,代价是丢弃最旧的条目,即最近访问的条目优先于其他条目:

@Testpublic void givenLinkedHashMap_whenRemovesEldestEntry_thenCorrect() { LinkedHashMap<Integer, String> map = new MyLinkedHashMap<>(16, .75f, true); map.put(1, null); map.put(2, null); map.put(3, null); map.put(4, null); map.put(5, null); Set<Integer> keys = map.keySet(); assertEquals("[1, 2, 3, 4, 5]", keys.toString()); map.put(6, null); assertEquals("[2, 3, 4, 5, 6]", keys.toString()); map.put(7, null); assertEquals("[3, 4, 5, 6, 7]", keys.toString()); map.put(8, null); assertEquals("[4, 5, 6, 7, 8]", keys.toString());}

我们看到当增加新条目时,在键set开头的最老的条目丢失了。

其他方面 并发

和HashMap一样,LinkHashMap 实现没有同步功能,所以如果多个线程同时访问时,需要在外部增加同步控制。可以使用这种方式创建:

Map m = Collections.synchronizedMap(new LinkedHashMap());

与HashMap不同的是什么操作会有结构性修改,顺序访问LInkHashMap,仅调用get 操作就会有结构性修改,另外put和remove也如此。

性能说明

与HashMap一样,LInkHashMap执行基本的Map操作,如add , remove以及 contain 操作时间都是常量,只要hash函数有足够的维度,也支持存储null 键和值。

但LInkHashMap的常量时间要比HashMap要稍大,因为需要额外维护双向链表。迭代LInkHashMap集合与HashMap一样都是线性O(n),LInkHashMap性能要优于HashMap。这是因为LInkHashMap的元素数量与容量无关,HashMap的n 是容量和size的和,即O(size+capacity)。

载入因子和初始化容量与HashMap一样,但对于LinkHashMap的影响要小,因为迭代并不受容量影响。

总结

本文我们学习了LinkHashMap,它是Map接口最重要的实现。通过探索其特性、与HashMap的差异、内部工作原理及应用场景。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。