LinkedHashMap 如何实现排序

目录

    • 一、LinkedHashMap
    • 二、排序实现
    • 三、代码片段分析

一、LinkedHashMap

    LinkedHashMap 是 Java 中的一个集合类,它是 HashMap 的一个子类,继承了 HashMap 的所有特性,并且在此基础上增加了一个双向链表来维护元素的插入顺序或者访问顺序。LinkedHashMap 通常用于需要保持插入顺序或者访问顺序的场合。

在这里插入图片描述
    
以下是 LinkedHashMap 的一些特点:

  • 顺序性:可以按照插入顺序或者访问顺序来迭代映射中的元素。
  • 性能:与 HashMap 类似,LinkedHashMap 在大多数情况下也提供了常数时间的性能。
  • 内存消耗:相比于 HashMap,LinkedHashMap 会消耗更多的内存,因为它需要额外的内存来维护双向链表。
  • LinkedHashMap 可以通过构造函数来指定是否按照插入顺序或者访问顺序来迭代:

默认情况下,LinkedHashMap 按照插入顺序来迭代。
如果在构造函数中传入 accessOrder 参数为 true,则按照访问顺序来迭代。
    

二、排序实现

    LinkedHashMap继承自HashMap并添加了一个双向链表来维护元素的插入顺序或访问顺序。以下是LinkedHashMap` 实现排序的原理和方法:

  1. 插入顺序排序:LinkedHashMap 默认按照元素的插入顺序进行排序。当元素被插入到 LinkedHashMap中时,它们会按照插入的顺序排列在双向链表中。即使后续元素的值被更新,它们在链表中的位置也不会改变,除非手动调用 remove 方法或者通过迭代器显式地删除元素。

  2. 访问顺序排序:可以通过在创建 LinkedHashMap实例时设置 accessOrder 参数为 true 来启用访问顺序排序。在这种模式下,每次通过 get 方法访问一个元素时,该元素会被移动到双向链表的末尾,从而保证最近访问的元素在链表的末尾。

  3. 按值排序:如果需要按照值对 LinkedHashMap 进行排序,可以使用 Collections.sort 方法或者 Java 8 引入的 Stream API。例如,可以使用 entrySet().stream().sorted(Map.Entry.comparingByValue()) 来对元素进行排序,然后通过 forEachOrderedcollect 方法将排序后的元素放入一个新的 LinkedHashMap 中。

  4. 自定义排序:如果 LinkedHashMap中的值不实现 Comparable 接口,可以通过提供一个自定义的 Comparator 来实现排序。例如,使用 Map.Entry.comparingByValue(Comparator.comparing(Player::getScore)) 来对包含自定义对象的 LinkedHashMap`进行排序。
        

三、代码片段分析

LinkedHashMap 按照元素的插入顺序进行排序的代码实现主要依赖于其内部的双向链表结构。以下是一些关键的代码片段,展示了 LinkedHashMap 如何维护插入顺序:

  1. 内部类 EntryLinkedHashMap 定义了一个内部类 Entry,继承自 HashMap.Node,并添加了两个新的引用 beforeafter 用于维护双向链表。

    static class Entry<K,V> extends HashMap.Node<K,V> {Entry<K,V> before, after;Entry(int hash, K key, V value, Node<K,V> next) {super(hash, key, value, next);}
    }
    
  2. 构造方法LinkedHashMap 提供了一个构造方法,允许设置 accessOrder 参数,默认为 false,表示按照插入顺序排序。

    public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {super(initialCapacity, loadFactor);this.accessOrder = accessOrder;
    }
    
  3. 插入操作:在 put 方法中,LinkedHashMap 调用 newNode 方法创建新的 Entry,并通过 linkNodeLast 方法将其添加到双向链表的末尾。

    Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {LinkedHashMap.Entry<K,V> p = new LinkedHashMap.Entry<K,V>(hash, key, value, e);linkNodeLast(p);return p;
    }
    
  4. 维护链表linkNodeLast 方法将新节点添加到双向链表的末尾,并更新 headtail 指针。

    private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {LinkedHashMap.Entry<K,V> last = tail;tail = p;if (last == null)head = p;else {p.before = last;last.after = p;}
    }
    
  5. 迭代顺序LinkedHashMap 重写了 get 方法,在返回值之前,如果 accessOrderfalse(即按照插入顺序),则不需要调整链表。

    public V get(Object key) {Node<K,V> e;if ((e = getNode(hash(key), key)) == null)return null;if (accessOrder)afterNodeAccess(e);return e.value;
    }
    
  6. 迭代器LinkedHashMap 的迭代器会根据双向链表的顺序遍历元素,从而保证了迭代顺序与插入顺序相同。

    通过这些代码实现,LinkedHashMap能够按照元素的插入顺序进行排序。当 accessOrder 设置为 true 时,LinkedHashMap会转变为按照访问顺序排序,这通常是通过 afterNodeAccess 方法实现的,该方法会在访问元素时将其移动到链表的末尾。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/141314.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Day26_0.1基础学习MATLAB学习小技巧总结(26)——数据插值

利用空闲时间把碎片化的MATLAB知识重新系统的学习一遍&#xff0c;为了在这个过程中加深印象&#xff0c;也为了能够有所足迹&#xff0c;我会把自己的学习总结发在专栏中&#xff0c;以便学习交流。 参考书目&#xff1a; 1、《MATLAB基础教程 (第三版) (薛山)》 2、《MATL…

C++ STL中sort函数

STL的sort算法&#xff0c;数据量大时采用QuickSort快排算法&#xff0c;分段归并排序。一旦分段后的数据量小于某个门槛&#xff08;16&#xff09;&#xff0c;为避免QuickSort快排的递归调用带来过大的额外负荷&#xff0c;就改用Insertion Sort插入排序。如果递归层次过深&…

C++入门基础知识69(高级)——【关于C++ 动态内存】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C 动态内存的相关内容&#xff01; 目录…

[产品管理-19]:NPDP新产品开发 - 17 - 产品设计与开发工具 - 实体化设计工具:联合分析、功能分析、FAST技术图和逆向工程

目录 前言&#xff1a; 一、什么是实体化设计 1.1 什么是实体化设计 1、定义与概述 2、设计流程 3、关键要素 4、应用领域 5、举例说明 1.2 实体化设计与概念设计的区别 实体化设计 概念设计 区别归纳 1.3 实体化设计与初步设计、规格设计的区别 1、定义与目的 …

51单片机-LCD1602(液晶显示屏)- 写驱动

时间永远是检验真理唯一标准&#xff01;Whappy&#xff01; 主要简单写出几个驱动 初始化、显示字符、显示字符串、显示整形数据、有符号数据、十六进制、二进制&#xff01; void LCD_Init(); void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char); vo…

平安养老险阜阳中心支公司开展金融教育宣传专项活动

为全面深入开展“金融教育宣传月”的各项工作&#xff0c;不断完善金融惠民利民举措&#xff0c;提升金融服务质效&#xff0c;帮助基层群众增强维权意识、防非反诈的自我保护能力。近日&#xff0c;平安养老保险股份有限公司&#xff08;以下“平安养老险”&#xff09;阜阳中…

【Node.js】RabbitMQ 延时消息

概述 在 RabbitMQ 中实现延迟消息通常需要借助插件&#xff08;如 RabbitMQ 延迟队列插件&#xff09;&#xff0c;因为 RabbitMQ 本身不原生支持延迟消息。 延迟消息的一个典型场景是&#xff0c;当消息发布到队列后&#xff0c;等待一段时间再由消费者消费。这可以通过配置…

带你0到1之QT编程:十一、掌握Containers容器艺术,一网打尽开发利器

此为QT编程的第十一谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01; …

npm install报错,gyp verb `which` failed Error: not found: python

主要错误 gyp verb which failed Error: not found: python2 gyp ERR! configure error gyp ERR! stack Error: Cant find Python executable "python", you can set the PYTHON env variable. npm ERR! node-sass4.14.1 postinstall: node scripts/build.js 全部错…

几分钟学会搭建一个自己的外卖霸王餐系统

大家好&#xff0c;我是鲸天科技千千&#xff0c;大家都知道我是做小程序开发的&#xff0c;平时会给大家分享一些互联网相关的创业项目&#xff0c;感兴趣的可以跟我关注一下。 搭建一个首先就是要搭建一个自己的霸王餐小程序&#xff0c;我们自己的工作就是把这个小程序推广…

合肥鲸天科技的外卖会员卡系统有人做过吗?赚钱吗?

我们先来了解一下这个合肥鲸天科技&#xff0c;通过我在网上找到的资料和企业查询&#xff0c;这家公司还是很有实力的&#xff0c;合肥鲸天科技有限公司也是欢迎有合作的人到公司来进行一个考察和合作其他一些项目的。 外卖会员卡简介绍&#xff1a; 这个外卖会员卡&#xf…

地震勘探原理视频总结(1-6)

目录 一、为什么要学好这门课&#xff1f; 1.1 为什么要学这门课&#xff08;为啥学&#xff09;&#xff1f; 1.2 课程包括哪些主要内容&#xff08;学什么&#xff09;&#xff1f; 1.3 如何学好这门课&#xff08;怎么学&#xff09;&#xff1f; 二、石油的生成与聚集…

linux 操作系统下的cut命令介绍和使用案例

linux 操作系统下的cut命令介绍和使用案例 在 Linux 操作系统中&#xff0c;cut 命令是一个用于文本处理的命令行工具&#xff0c;允许用户从文件或管道数据中提取特定部分并将结果输出到标准输出 1. cut 命令简介 cut 命令主要用于从文本文件中提取特定的字段、字节或字符。…

01.AI推出Yi模型家族:多维度能力的展示

人工智能咨询培训老师叶梓 转载标明出处 01.AI公司提出了Yi模型家族&#xff0c;这一系列语言和多模态模型展示了强大的多维能力&#xff0c;旨在成为下一代计算平台&#xff0c;通过大规模数据和精心设计的训练过程&#xff0c;实现接近人类智能的模型。Yi模型家族基于6B和34…

CrossOver24.0.5破解版免费下载和永久激活图文教程,苹果电脑怎么玩《黑神话:悟空》

CrossOver24可以玩《黑神话&#xff1a;悟空》么&#xff1f;答案是可以的。 1、首先我们需要下载CrossOver24软件。 CrossOver24安装包夸克网盘链接&#xff1a;https://pan.quark.cn/s/35e64d746778 2、下载完成后&#xff0c;我们双击CrossOver.pkg开始安装&#xff0c;然…

【Vue】2

1 Vue 生命周期 Vue生命周期&#xff1a;一个 Vue 实例从 创建 到 销毁 的整个过程 创建(create)阶段&#xff1a;组件实例化时&#xff0c;初始化数据、事件、计算属性等挂载(mount)阶段&#xff1a;将模板渲染并挂载到 DOM 上更新(update)阶段&#xff1a;当数据发生变化时…

【Android】Room—数据库的基本操作

引言 在Android开发中&#xff0c;数据持久化是一个不可或缺的部分。随着应用的复杂度增加&#xff0c;选择合适的数据存储方式变得尤为重要。Room数据库作为Android Jetpack架构组件之一&#xff0c;提供了一种抽象层&#xff0c;使得开发者能够以更简洁、更安全的方式操作SQ…

八股(8)——Spring,SpringBoot

八股&#xff08;8&#xff09;——Spring&#xff0c;SpringBoot 基础1.Spring 是什么&#xff1f;特性&#xff1f;有哪些模块&#xff1f;Spring 有哪些特性呢&#xff1f; 2.Spring 有哪些模块呢&#xff1f;3.Spring 有哪些常用注解呢&#xff1f;Web 开发方面有哪些注解呢…

P5425 [USACO19OPEN] I Would Walk 500 Miles G

*原题链接* 很离谱的题。首先可以想到暴力连边&#xff0c;整个图为一个完全图&#xff0c;将所有的边选出来&#xff0c;然后从小到大一条条加入&#xff0c;当剩下集合数量 <K 的时候就结束。答案为加入的最后一条边的大小。如果用prim算法的话时间复杂度为。足以通过此题…

Python [ GUI编程自学 ],虽然但是,还是想出一个系列

本文主要介绍了GUI组件的其他常用组件部分&#xff1a;optionmenu选项菜单&#xff0c;scale滑块&#xff1b;颜色框、文件选择框&#xff0c;读取文件内容&#xff1b;简单对话框、通用消息、ttk子模块问题&#xff1b; 一系列GUI编程&#xff0c;有相关的专栏&#xff0c;欢迎…