LinkedHashMap的特性:
Linked内部含有一个private transient Entry header;来记录元素插入的顺序或者是元素被访问的顺序。利用这个线性结构的对象,可以帮助记录entry加入的前后顺序或者记录entry被访问的频率(最少被访问的entry靠前,最近访问的entry靠后)。大致的过程如下:
new LinkedHashMap(10, 0.75, true);
其中前面两个参数就是HashMap构造函数需要的参数,后面的true表明LinkedHashMap按照访问的次序来排序。
按照访问的次序来排序的含义:当调用LinkedHashMap的get(key)或者put(key, value)时,碰巧key在map中被包含,那么LinkedHashMap会将key对象的entry放在线性结构的最后。
按照插入顺序来排序的含义:调用get(key), 或者put(key, value)并不会对线性结构产生任何的影响。
正是因为LinkedHashMap提供按照访问的次序来排序的功能,所以它才需要改写HashMap的get(key)方法(HashMap不需要排序)和HashMap.Entry的recordAccess(HashMap)方法
public Object get(Object key) {
Entry e = (Entry)getEntry(key);
if (e == null)
return null;
e.recordAccess(this);
return e.value;
}
void recordAccess(HashMap m) {
LinkedHashMap lm = (LinkedHashMap)m;
if (lm.accessOrder) {
lm.modCount++;
remove();
addBefore(lm.header);
}
}
注意addBefore(lm.header)是将该entry放在header线性表的最后。(参考LinkedHashMap.Entry extends HashMap.Entry 比起HashMap.Entry多了before, after两个域,是双向的)
至于put(key, value)方法, LinkedHashMap不需要去改写,用HashMap的就可以了,因为HashMap在其put(key, value)方法里边已经预留了e.recordAccess(this);
还有一个方法值得关注:
protected boolean removeEldestEntry(Map.Entry eldest) {
return false;
}
当调用put(key, value)的时候,HashMap判断是否要自动增加map的size的作法是判断是否超过threshold, LinkedHashMap则进行了扩展,如果removeEldestEntry方法return false;(默认的实现),那么LinkedHashMap跟HashMap处理扩容的方式一致;如果removeEldestEntry返回true,那么LinkedHashMap会自动删掉最不常用的那个entry(也就是header线性表最前面的那个)。
正如LinkedHashMap的文档所说,LinkedHashMap简直就是为了实现LRU Cache(Least Recently Used)而编写的。正因为如此,在oscache或者是ehcache都使用到了LinkedHashMap。(oscache中是否使用LRU是可以配置的)
<!-- google_ad_section_end -->
分享到:
相关推荐
若设为`false`(默认),则按照插入顺序排序。 1. `public LinkedHashMap(int initialCapacity, float loadFactor)`:创建一个空的LinkedHashMap,指定初始容量和加载因子。 2. `public LinkedHashMap(int ...
- **有序性**:`LinkedHashMap`保证了元素的插入顺序或者访问顺序。如果是在迭代遍历或用迭代器获取元素时,元素会按照它们被插入的顺序返回。此外,如果设置了构造函数的`accessOrder`参数为`true`,则元素会被...
- 当 `accessOrder` 参数设置为 `false`(默认情况)时,元素按照插入顺序排序。当新元素被添加到 HashMap 中,它会被添加到链表的尾部。 3. **访问顺序**: - 当 `accessOrder` 参数设置为 `true` 时,元素会...
在插入顺序排序时,LinkedHashMap会将元素插入到双向链表的尾部。 LinkedHashMap的源码分析展示了其链表结构和哈希表结构的实现细节,展示了LinkedHashMap如何实现按插入顺序和访问顺序排序的。
- **访问顺序**:除了插入顺序外,`LinkedHashMap`还可以根据元素的访问顺序排序。 - **性能**:相比`HashMap`,由于额外维护了链表,因此在插入和删除操作上可能稍慢一些,但总体上仍然接近于O(1)。 #### 3. ...
同时,LinkedHashMap也可以保持插入时的顺序,这样可以方便地实现分数排序。 使用LinkedHashMap进行分数排序是Java中的一种非常实用的方法,特别是在学生成绩统计的问题中。它可以提高排序效率,避免传统排序方法的...
这种特性使得`LinkedHashMap`在需要保持插入顺序或访问顺序的场景下非常有用。 `TreeMap`是基于红黑树数据结构实现的Map,它能自动对键进行排序。如果键实现了Comparable接口,那么`TreeMap`会按照自然顺序排序;...
如果 `accessOrder` 属性为 true,LinkedHashMap 将移动该节点到链表的末尾,从而实现按访问顺序排序。 2. **afterNodeInsertion(boolean evict)**: 在插入新节点后调用。在这个方法中,除了添加新节点到哈希表和...
如果想要按照插入顺序排序,直接使用LinkedHashMap即可。如果需要按照访问顺序排序,可以在构造时传入`true`参数,这样每次访问元素时都会将其移动到末尾。 - **转换为List并使用Collections.sort()** 更通用的...
除了插入顺序,LinkedHashMap还支持按照访问顺序排序,即每次访问某个元素后,该元素会被移动到链表末尾。只需在创建LinkedHashMap时设置`accessOrder`为`true`即可启用这一特性。这样,频繁访问的元素会相对靠后,...
在json2.1这个特定版本中,`JSONObject`可能没有保留插入顺序,因此当从List转换时,元素的顺序可能会被打乱。 为了克服这个问题,我们可以采取以下几种策略: 1. **使用保留顺序的JSON库**:例如,Jackson库的`...
LinkedHashMap保持了插入顺序或者访问顺序;TreeMap则使用红黑树结构,元素按照键的自然排序或自定义比较器排序。 在Java集合排序方面,我们主要关注List和Map。对于List,可以使用Collections.sort()方法进行排序...
TreeSet基于TreeMap,其元素按自然排序或自定义比较器排序。 下面是一些关于这些类的使用示例: ```java Map, String> map1 = new HashMap(); // 插入无序元素 Map, String> map2 = new LinkedHashMap(); // 插入...
LinkedHashMap是Java中的一种特殊类型的HashMap,它保留了插入顺序,即按照元素插入的先后顺序进行排序
HashMap是无序的,而LinkedHashMap则保持了插入顺序或者按照访问顺序排序。在Intent中,我们通常使用Serializable或Parcelable接口来序列化对象以便传递。因为HashMap不保证顺序,所以如果需要在Intent中传递一个...
`LinkedHashMap`是`HashMap`的一个子类,它维护了一个双向链表来保持插入顺序,或者在构造时指定按照访问顺序排序。这意味着,当元素被访问时,会被移动到链表的末尾。这种特性使得`LinkedHashMap`在需要保持插入...
LinkedHashMap, String>是一个基于链表的实现,它可以按照插入顺序保存键值对。我们可以使用以下代码来实现一个按值排序的Map: ```java public Map, String> sortMapByValue(Map, String> oriMap) { Map, String>...
如果你想按照插入顺序或者访问顺序对值进行排序,可以考虑使用LinkedHashMap。但是请注意,这并不意味着值本身会被排序,而是插入或访问的顺序被保留。 3. 手动排序:你可以遍历HashMap,获取所有的value,然后使用...
* `public LinkedHashMap(int initialCapacity, float loadFactor)`: 带有初始容量和加载因子的构造方法,链表中的元素默认按照插入顺序排序。 * `public LinkedHashMap(int initialCapacity)`: 带有初始容量的构造...
LinkedHashMap保持插入顺序或访问顺序;TreeMap基于红黑树,按键的自然顺序或自定义比较器排序。 内部类是Java中一个独特的特性,允许在一个类的内部定义另一个类。根据其可见性和位置,内部类可以分为以下几类: ...