Java常见集合框架(二十): Map之LinkedHashMap、SortedMap、NavigableMap、TreeMap_navigablemap和treemap-程序员宅基地

技术标签: Java  Java常见集合框架  java  NavigableMap  SortedMap  TreeMap  LinkedHashMap  

LinkedHashMap

public class LinkedHashMap extends HashMap implements Map

  1. Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。
  2. 不是同步的,fail-fast。
  3. 允许 null key or value。
  4. 继承HashMap,LinkedHashMap保证Map有序(插入顺序、访问顺序)。

成员变量

    /**
     * 双重链接列表头节点
     */
    private transient Entry<K,V> header;

    /**
     * 该linked hash map的排序方式
     * 排序模式 - 对于访问顺序,为 true;对于插入顺序,则为 false
     */
    private final boolean accessOrder;

LinkedHashMap重新定义了内部类Entry,实现双向链表。

	/**
     * LinkedHashMap entry.
     */
    private static class Entry<K,V> extends HashMap.Entry<K,V> {
        //用于实现双向链表
        Entry<K,V> before, after;
}

构造方法

    public LinkedHashMap(int initialCapacity,
			 float loadFactor, boolean accessOrder) {
        super(initialCapacity, loadFactor);
        this.accessOrder = accessOrder;
    }

有源码看出,LinkedHashMap构造方法调用父类HashMap构造方法,再调用LinkedHashMap覆写的init方法,从而实现双重链表初始化。

    void init() {
        header = new Entry<K,V>(-1, null, null, null);
        header.before = header.after = header;
    }

put方法

LinkedHashMap并未重写HashMap.put方法。而是重写了父类HashMap.put方法中void addEntry(int hash, K key, V value, int bucketIndex) 和void createEntry(int hash, K key, V value, int bucketIndex),提供了双重链表的实现。

    void addEntry(int hash, K key, V value, int bucketIndex) {
        createEntry(hash, key, value, bucketIndex);
        Entry<K,V> eldest = header.after;
        if (removeEldestEntry(eldest)) {
            removeEntryForKey(eldest.key);
        } else {
            if (size >= threshold)
                resize(2 * table.length);
        }
    }
    
	void createEntry(int hash, K key, V value, int bucketIndex) {
        HashMap.Entry<K,V> old = table[bucketIndex];
		Entry<K,V> e = new Entry<K,V>(hash, key, value, old);
        table[bucketIndex] = e;
        e.addBefore(header);
        size++;
    }

get方法

LinkedHashMap覆写了父类的get方法,区别在于,査找到对应元素后,若accessOrder为true时,更新访问顺序,即将最新访问元素移到链表头部,并,即LRU算法思想,可用做LRU缓存。accessOrder为false时,因其迭代顺序即为默认插入顺序,故不用做额外变动。
注意accessOrder为true时:迭代顺序为从近期访问最少到近期访问最多的顺序。
例如key插入顺序:1,2,3。get(2)之后,map迭代顺序顺序为:1,3,2。

    public V get(Object key) {
	    //调用父类HashMap.getEntry方法,获取对应entry
        Entry<K,V> e = (Entry<K,V>)getEntry(key);
        if (e == null)
            return null;
        e.recordAccess(this);
        return e.value;//返回值
    }
    
	 void recordAccess(HashMap<K,V> m) {
            LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
            if (lm.accessOrder) {//访问模式,更新访问顺序,LRU
                lm.modCount++;
                remove();
                addBefore(lm.header);
            }
        }

LinkedHashMap继承HashMap,拥有其特性,重新定义Entry从而增加了双重链表特性。提供两种排序方式:访问顺序、插入顺序。

SortedMap

public interface SortedMap extends Map

  1. 进一步提供关于键的总体排序 的 Map。
  2. 键的自然排序可由 Comparable 或 Comparator方式实现。

NavigableMap

public interface NavigableMap extends SortedMap

  1. 扩展的 SortedMap,具有了针对给定搜索目标返回最接近匹配项的导航方法。
  2. 可以按照键的升序或降序访问和遍历 NavigableMap。

TreeMap

public class TreeMap extends AbstractMap implements NavigableMap, Cloneable, java.io.Serializable

  1. 基于红黑树(Red-Black tree)的 NavigableMap 实现。
  2. 该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
  3. 不是同步的,fail-fast。

成员变量

    /**
     * 自然排序比较器
     */
    private final Comparator<? super K> comparator;
	//根节点
    private transient Entry<K,V> root = null;

    /**
     * key-value 映射对数
     */
    private transient int size = 0;

    /**
     * 树的修改次数
     */
    private transient int modCount = 0;

构造方法

	/**
	 * 使用键的自然顺序构造一个新的、空的树映射。
	 */
    public TreeMap() {
        comparator = null;
    }
    
	/**
	 * 构造一个与指定有序映射具有相同映射关系和相同排序顺序的新的树映射。
	 */
    public TreeMap(SortedMap<K, ? extends V> m) {
        comparator = m.comparator();
        try {
            buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
        } catch (java.io.IOException cannotHappen) {
        } catch (ClassNotFoundException cannotHappen) {
        }
    }

百度百科解释红黑树:

  1. 红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。
  2. 红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。
  3. 它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。

TreeMap基于红黑树,Map有序,适用于查找搜索场景。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/a355586533/article/details/78330738

智能推荐

Android中,TextView跑马灯(marquee)问题-程序员宅基地

文章浏览阅读453次,点赞3次,收藏10次。Textiew不要设置固定高度,设置成wrap_content就好了。外面套一层Linearayout布局。文字不停回到初始位置。

AM335x核心频率设置和DDR3参数调整方法_am335x ddr-程序员宅基地

文章浏览阅读7.1k次,点赞19次,收藏17次。AM3352如何计算和设置DDR3内存参数AM335x DDR3 Software Leveling Program_am335x ddr

5.2 创建个人中心页面-前端部分_个人中心前端代码-程序员宅基地

文章浏览阅读7.3k次,点赞10次,收藏22次。5.2 创建个人中心页面-前端部分_个人中心前端代码

使用virtualenv新建虚拟环境出现:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd3 in position 319-程序员宅基地

文章浏览阅读647次。报错如图所示:找到该文件,更改为如图所示:成功解决:_unicodedecodeerror: 'utf-8' codec can't decode byte 0xd3 in position 0: inva

c语言十六实验答案,《C语言》上机实验题及参考答案-程序员宅基地

文章浏览阅读1.6k次。C语言编程题精选1、 编程实现对键盘输入的英文名句子进行加密。用加密方法为,当内容为英文字母时其在26字母中的其后三个字母代替该字母,若为其它字符时不变。 2、 编程实现将任意的十进制整数转换成R进制数(R在2-16之间)。3、 从键盘输入一指定金额(以元为单位,如345.78),然后显示支付该金额的各种面额人民币数量,要求显示100元、50元、10元、5元、2元、1元、5角、1角、5分、1分各多..._istudy c语言 实验16课内实践16-综合练习

PhD English Research —— Writing_phd english class 研究-程序员宅基地

文章浏览阅读137次。English Research Writing_phd english class 研究

随便推点

记录el-input type=number限制长度el-input使用_el-input-number限制输入长度-程序员宅基地

文章浏览阅读5.2k次。<el-input type="number" oninput="if(value.length>10)value=value.slice(0,10)" @keyup.enter.native="query()" :max="99999999"> </el-input>oninput 是个自定义事件 在事件里面获取输入的数字长度,来进行判断如果大于规定长度就进行剪切。keyup.enter.native 是个键盘回车事件,当按下Enter键时触发query()事件_el-input-number限制输入长度

弹出修改模态框_如何通过操作窗口改变模态对话框内容-程序员宅基地

文章浏览阅读1.7k次。开发工具与关键技术:Visual Studio 2015作者:杨镇虹撰写时间:2019.04.20一、 html设置的一个按钮button布局 图11、给这个按钮一个onclick点击事件,里面给一个元素openUpdateModal就是用来修改模态框打开的这个按钮点击到这个元素图12、首选拿到这个按钮给的点击事件的这个元素openUpdateModal(open)打开(Update..._如何通过操作窗口改变模态对话框内容

【Web前端】Ajax超详解_前端ajax-程序员宅基地

文章浏览阅读1.8k次,点赞4次,收藏15次。本文共计两万四千字,详细的介绍了前后端交互的内容,以及Ajax的实现方式,包括XHR、Fetch和Axios。_前端ajax

为JSF定做的应用程序框架(一)-程序员宅基地

文章浏览阅读142次。JavaServer Faces (JSF) 是用于 Java Web 应用程序的第一个标准化的用户界面框架。 而 Seam 是一个扩展 JSF 的强大的应用程序框架。在这个由三部分组成的新系列中的第一篇文章中,发现这两种框架之间的互补性。Dan Allen 介绍了 Seam 对 JSF 生命周期的增强,包括上下文状态管理、 RESTful URL、Ajax remoting、适当的异常..._jsf界面框架颜色怎么弄

Django在根据models生成数据库表时报 __init__() missing 1 required positional argument: 'on_delete'...-程序员宅基地

文章浏览阅读115次。code: 1 #encoding=utf-8 2 from django.db import models 3 # Create your models here. 4 class BookInfo(models.Model): #创建书本信息类,继承models.Model 5 booktitle=models.CharField(max_length=20)..._book = models.foreignkey(oenpageinfo) typeerror: __init__() missing 1 requir

Please use a locale setting which supports utf-8_python can't change the filesystem locale after lo-程序员宅基地

文章浏览阅读5.1k次,点赞3次,收藏8次。原地址:https://wiki.yoctoproject.org/wiki/TipsAndTricks/ResolvingLocaleIssuesWhat to do when bitbake says " Sad Locale, Need UTF-8"If bitbake says:Please use a locale setting which supports utf-8..._python can't change the filesystem locale after loading so we need a utf-8 w

推荐文章

热门文章

相关标签