有序的Map集合_map集合特点

有序的Map集合_map集合特点我们通常使用的Map集合是HashMap,在大多数情况下HashMap可以满足我们的要求,但是HashMap有一个缺点:HashMap是无序的,即其迭代顺序与其key或value的大小无关。而在某些情况下,如果我们需要Map集合里的元素有序,那么HashMap是不能满足我们的要求的。那么有没有有序的Map集合呢?有,Java提供了两种有序的Map集合:LinkedHashMap和TreeM…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

  我们通常使用的Map集合是HashMap,在大多数情况下HashMap可以满足我们的要求,但是HashMap有一个缺点:HashMap是无序的,即其迭代顺序与其key或value的大小无关。而在某些情况下,如果我们需要Map集合里的元素有序,那么HashMap是不能满足我们的要求的。

那么有没有有序的Map集合呢?有,Java提供了两种有序的Map集合:LinkedHashMapTreeMap

(一)LinkedHashMap

LinkedHashMap继承了HashMap,是HashMap的子类。

有序的Map集合_map集合特点

其实LinkedHashMap与HashMap区别不大,也是通过计算键的hash值,映射到hash表中,那么LinkedHashMap是如何实现有序的呢?

LinkedHashMap不仅维护着一个hash表,而且还维护着一个双向链表,而这个双向链表里的元素就是有序的。

LinkedHashMap的Entry继承于HashMap的Entry,并且增加了before和after属性。

有序的Map集合_map集合特点

 

可以看到before和after的类型都是Entry,LinkedHashMap通过before和after来构建双向链表。

LinkedHashMap的内部结构如图所示:

有序的Map集合_map集合特点

 

LinkedHashMap有两种排序方式:插入排序和访问排序(修改或访问一个元素后,将该元素移到队列末尾),默认是插入排序。使用accessOrder来标记使用哪种排序方式,accessOrder==true时,表示使用访问排序默认为false;注意:LinkedHashMap的有序不是keyvalue的自然顺序

LinkedHashMap的插入:

put():

LinkedHashMap的put方法和HashMap的相同,不过LinkedHashMap重写了newNode方法,在插入时,会判断双向链表是否为空,如果为空,则将该Entry作为头结点head,否则在双向链表末尾插入该Entry;如果更新值(key相同),则会判断accessOrder是否为true,如果为true,则将该Entry移到双向队列的尾部。

get():

LinkedHashMap在get的时候,会判断accessOrder是否为true,即是否按访问顺序排序,如果是true,则会把该Entry移到双向队列的尾部。然后再返回value。

LinkedHashMap的迭代:

LinkedHashMapIterator实现了迭代器的功能,其是对双向循环链表的遍历操作。但是这个迭代器是abstract的,不能直接被对象所用。

有序的Map集合_map集合特点

LinkedHashMap中的LinkedKeyIteratorLinkedValueIteratorLinkedEntryIterator都继承了LinkedHashMapIterator,并且实现了Iterator接口,我们可以使用上面三种迭代器来迭代keyvalueentry三种迭代器迭代的是同一个双向链表,即迭代的元素是相同的,只是返回的类型不同。

 

遍历TreeMap的键值对

LinkedHashMap map = new LinkedHashMap();
Integer integ = null;
Iterator iter = map.entrySet().iterator();
while(iter.hasNext()) {
    Map.Entry entry = (Map.Entry)iter.next();
    // 获取key
    key = (String)entry.getKey();
        // 获取value
    integ = (Integer)entry.getValue();
}

(二)TreeMap

TreeMap也是一个有序的Map集合,其底层是一颗红黑树,该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。

有序的Map集合_map集合特点

TreeMap的Entry结构如下:

有序的Map集合_map集合特点

可以看出来TreeMap的Entry其实是一个树节点,构建了一颗红黑树。而entry的插入,就是在红黑树中新增一个节点,并调整红黑树。

TreeMap的插入:

put():

如果Comparator 为空,会使用key进行比较,按照从小到大的次序插入到红黑树中。

如果Comparator 不为空,则根据Comparator来进行比较。

TreeMap的迭代:

有序的Map集合_map集合特点

PrivateEntryIterator实现了迭代器的功能,其是对红黑树进行遍历,返回的是红黑树中的有序序列。但是这个迭代器是abstract的,不能直接被对象所用。迭代时使用的是EntryIterator,ValueIterator,KeyIterator等迭代器。

有序的Map集合_map集合特点

除了顺序遍历,TreeMap还可以逆序遍历,由于TreeMap中的元素是从小到大的顺序排列的。因此,顺序遍历,就是从第一个元素开始,逐个向后遍历;而倒序遍历则恰恰相反,它是从最后一个元素开始,逐个往前遍历。

有序的Map集合_map集合特点

 

遍历TreeMap的键值对

TreeMap map = new TreeMap ();
Integer integ = null;
Iterator iter = map.entrySet().iterator();
while(iter.hasNext()) {
    Map.Entry entry = (Map.Entry)iter.next();
    // 获取key
    key = (String)entry.getKey();
        // 获取value
    integ = (Integer)entry.getValue();
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/192963.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pip install 使用国内镜像

    pip install 使用国内镜像让PIP源使用国内镜像,提升下载速度和安装成功率。对于Python开发用户来讲,PIP安装软件包是家常便饭。但国外的源下载速度实在太慢,浪费时间。而且经常出现下载后安装出错问题。所以把PIP安装源替换成国内镜像,可以大幅提升下载速度,还可以提高安装成功率。国内源:新版ubuntu要求使用https源,要注意。清华:https://pypi.tuna.tsinghua.edu.cn/…

    2022年6月8日
    31
  • jmeter并发测试教程_jmeter多线程并发测试

    jmeter并发测试教程_jmeter多线程并发测试Jmeter是一款使用Java开发的,开源免费的,测试工具,主要用来做功能测试和性能测试(压力测试/负载测试).而且用Jmeter来测试RestfulAPI,非常好用。

    2022年9月29日
    0
  • ios屏蔽ota更新描述文件(苹果软件更新怎么关闭)

    前言iOS手机下载新系统文件后,老是提示更新升级,确实很烦人,且为了防止手机被不小心给升级了,可以按照以下方法让手机显示当前版本为最高版本,不会下载升级包进行安装升级。操作步骤1、Safari浏览器中输入网址ibeta.me进入网页,选择最右侧屏蔽OTA更新,点击立即安装则会立即下载一个描述文件。2、进入手机设置->通用->描述文件选择tvOS13BetaSoftwareProfile,点击安装3、安装成功后,会提示重启手机,点击重启

    2022年4月11日
    200
  • c语言long类型转换成string,如何在C ++中将long转换为string?「建议收藏」

    c语言long类型转换成string,如何在C ++中将long转换为string?「建议收藏」你可以使用stringstream。#include//…std::stringnumber;std::stringstreamstrstream;strstream<<1L;strstream>>number;标准库中通常会有一些专有的C函数供您的编译器使用。尽pipe如此,我更喜欢更“便携”的变体。C的方法是用sprintf,但这不是很安…

    2022年5月14日
    45
  • 进销存软件开源java_JSH_ERP 开源版J2EE进销存系统代码源码 v1.0.2「建议收藏」

    进销存软件开源java_JSH_ERP 开源版J2EE进销存系统代码源码 v1.0.2「建议收藏」JSH_ERP是一个完整开源版的J2EE进销存系统代码。很多人说JSH_ERP是目前唯一完整开源的进销存系统虽然目前只有进销存+财务的功能,但后面将会推出ERP的全部功能,大家一起努力吧JSH_ERP立志为中小企业提供免费好用的ERP软件,降低企业的信息化成本个人开发者也可以使用JSH_EPP进行二次开发,承接外包ERP项目初学JAVA的小伙伴可以下载源代码来进行学习交流系统部署初始账号:jsh,…

    2022年5月6日
    54
  • Mysql 练习题 及 答案

    Mysql 练习题 及 答案 –1.学生表Student(S,Sname,Sage,Ssex)–S学生编号,Sname学生姓名,Sage出生年月,Ssex学生性别–2.课程表 Course(C,Cname,T)–C–课程编号,Cname课程名称,T教师编号–3.教师表 Teacher(T,Tname)–T教师编号,Tname教师姓名–4.成绩表 SC(S,C,score)–S学生…

    2022年9月2日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号