双例集合(三)——双例集合的实现类之TreeMap容器类
Map接口有两个实现类,一个是HashMap容器类,另一个是TreeMap容器类。TreeMap容器类的使用在API上于HashMap容器类没有太大的区别。它们的区别主要体现在两个方面,一个是底层实现方式上,HashMap是基于Hash算法来实现的吗,而TreeMap是基于红黑树来实现的;另一个区别体现在功能上,虽然HashMap容器类的效率比较高,但是它无法实现排序操作。相对的,TreeMap虽然在效率上比不上HashMap,但是它能够实现对双例集合中元素的key进行排序操作。值得注意的是,TreeMap只支持对双例集合中的键key进行排序操作,这个也好理解,因为双例集合中的key与value是一一对应的关系,对key进行排序就相当于也对value进行了排序。
由于TreeMap容器类和HashMap容器类在使用上没有多大的区别,因此我们只要掌握好TreeMap中的排序操作再与HashMap容器类进行对比学习就可以很好地掌握TreeMap容器类了。
TreeMap容器类对键key的排序操作和之前我们介绍的TreeSet容器类对元素的排序操作是相似的。在使用它们的时候都需要给定排序规则,而对于排序规则它们二者都有两种给定排序规则的方式,一种是通过元素自身来实现比较规则,这种方式就是按照元素内定义的规则来实现排序;另一种是通过编程者自定义的比较器来实现比较规则。接下来对TreeMap中的这两种方式进行一一介绍。
首先介绍通过元素自身来实现比较规则的方式。这种方式是按照元素内定义的规则来实现排序的。这里我们用一个例子来进行说明,我们TreeMapTest类中实例化了一个TreeMap容器类对象map,在map对象中我们将它的key设置为类User,value的类型仍然为String,其中User类的代码如下所示。可以发现在User类中我们重写了compareTo方法,这个方法中定义比较规则——按照对象的userAge这个变量的大小进行排序。这时我们在TreeMapTest类中实例化User对象u1,u2和u3,将几个对象作为key添加容器map中去。接下来我们只要遍历容器map中的元素就能发现,它的结果已经按照User中定义的比较规则进行排序了。此处要注意的是,当遇到比较规则中的变量值是相同的情况,则系统会取另一个变量来按照这个新的变量的默认排序规则进行排序。比如在演示代码中我们的对象u2和u3的userAge这个变量的值都是20,那么这个是就会取userName这个变量来进行排序。比较结果为u3在u2的前面,因为按照系统默认的比较规则,字母g在字母l的前面。
package com.container.demo;import java.util.Objects;public class User implements Comparable<User>{private String usersName;private int usersAge;public String getUsersName() {return usersName;}public void setUsersName(String usersName) {this.usersName = usersName;}public int getUsersAge() {return usersAge;}public void setUsersAge(int usersAge) {this.usersAge = usersAge;}@Overridepublic String toString() {return "User{" +"usersName='" + usersName + '\'' +", usersAge=" + usersAge +'}';}public User(String usersName, int usersAge) {this.usersName = usersName;this.usersAge = usersAge;}public User() {}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;User user = (User) o;return usersAge == user.usersAge && Objects.equals(usersName, user.usersName);}@Overridepublic int hashCode() {return Objects.hash(usersName, usersAge);}//定义比较规则//正数:大,负数:小,0:相等@Overridepublic int compareTo(User o) {if(this.usersAge > o.usersAge)return 1;if(this.usersAge == o.usersAge){return this.usersName.compareTo(o.getUsersName());}return -1;}
}

接下来介绍使用自定义的比较器来实现排序的方法。这里我们仍然以一个例子来进行说明。首先在TreeMapTest类中实例化一个TreeMap容器类对象map1。我们把类Student类作为容器map1中key的类型,Sudent类的代码如下所示。将Student类和上面个的User类进行比较能够发现,在Student类中并没有重写compareTo方法,因此这个类中并没有实现排序规则。和上面一样我们也实例化了3个Student对象,将其添加到容器map1中,这时因为我们没有定义比较器,Student类中也没有实现比较规则,所以如果我们运行程序,那么程序就会在运行时报错提醒我们没有定义key的排序规则。如下图所示:

所以我们需要定义一个比较器,并将它使用到容器map1中。这里我们定义比较器StudentComparator,它的实现代码如下所示。原理就是比较器StudentComparator实现了接口Comparator,然后在这个比较器中重写了compare方法。定义比较器之后我们就需要将比较器应用到map1容器中,应用的方法和TreeSet容器类中应用比较器到容器中是一样的。TreeMap容器类的构造方法中提供了一个有参构造,这个参数就是比较器。所以我们只需要在实例化容器的时候将比较器作为参数传入构造方法中就能应用比较器到容器中了。这里要注意传入参数的形式,因为比较器的实质是一个非静态类,因此在另一个类中使用时需要进行实例化操作,为了方便我们只需要在需要传入参数的地方进行new 操作即可,不需要对实例化的对象进行实际接收。
package com.container.demo;
//比较器
import java.util.Comparator;
public class StudentComparator implements Comparator<Student> {//定义比较规则@Overridepublic int compare(Student o1, Student o2) {if(o1.getAge() >o2.getAge()){return 1;}if(o1.getAge() == o2.getAge()){return o1.getName().compareTo(o2.getName());}return -1;}}
import java.util.Objects;public class Student {private String name;private int age;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Student(String name, int age) {this.name = name;this.age = age;}public Student() {}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
package com.container.demo;import java.util.Map;
import java.util.Set;
import java.util.TreeMap;public class TreeMapTest {public static void main(String[] args) {//实例化TreeMap容器Map<User,String> map = new TreeMap<>();User u1 = new User("linyi",18);User u2 = new User("linling",20);User u3 = new User("lingzi",20);map.put(u1,"liyi");map.put(u2,"linling");map.put(u3,"lingzi");Set<User> keys = map.keySet();for (User key:keys) {System.out.println(key+"---"+map.get(key));}System.out.println("___________________________________");Map<Student,String> map1 = new TreeMap<>(new StudentComparator());Student s1 = new Student("linyi",18);Student s2 = new Student("linling",20);Student s3 = new Student("linger",20);map1.put(s1,"linyi");map1.put(s2,"linling");map1.put(s3,"linger");Set<Student> keys1 = map1.keySet();for (Student key:keys1) {System.out.println(key+"--------"+map1.get(key));}}
}
相关文章:
双例集合(三)——双例集合的实现类之TreeMap容器类
Map接口有两个实现类,一个是HashMap容器类,另一个是TreeMap容器类。TreeMap容器类的使用在API上于HashMap容器类没有太大的区别。它们的区别主要体现在两个方面,一个是底层实现方式上,HashMap是基于Hash算法来实现的吗,…...
[SAP ABAP] 运算符
1.算数运算符 算术运算符描述加法-减法*乘法/除法MOD取余 示例1 输出结果: 输出结果: 2.比较运算符 比较运算符描述示例 等于 A B A EQ B <> 不等于 A <> B A NE B >大于 A > B A GT B <小于 A < B A LT B >大于或等于 A > B A GE B <小…...
MSPM0G3507 ——GPIO例程讲解2——simultaneous_interrupts
主函数: #include "ti_msp_dl_config.h"int main(void) {SYSCFG_DL_init();/* Enable Interrupt for both GPIOA and GPIOB ports */NVIC_EnableIRQ(GPIO_SWITCHES_GPIOA_INT_IRQN); //启用SWITCHES——A的中断 NVIC_EnableIRQ(GPIO_S…...
某程序员:30岁了,老婆管钱,背着我买了50万股票,亏了20w,强制她清仓后又买了36万
“辛辛苦苦攒了几年钱,本想买房买车,结果全被老婆炒股亏掉了!” 近日,一位30岁的程序员大哥在网上吐苦水,引发了网友们的热议。 这位程序员大哥和妻子结婚后,一直秉持着“男主外,女主内”的传统…...
Docker常见面试题整理
文章目录 1. Docker 是什么?它解决了什么问题?2. Docker 和虚拟机(VM)的区别是什么?3、Docker三个核心概念4、如何构建一个 Docker 镜像?5、如何将一个 Docker 容器连接到多个网络?6、Docker Co…...
35 - 最后一个能进入巴士的人(高频 SQL 50 题基础版)
35 - 最后一个能进入巴士的人 -- sum(weight) over(order by turn) as total,根据turn升序,再求前面数的和 selectperson_name from(selectperson_name,sum(weight) over(order by turn) as totalfromQueue) new_Queue wheretotal<1000 order by total desc lim…...
WPF将dll文件嵌入到exe文件中
WPF将dll文件嵌入到exe文件中 第一步:打开.csproj文件,在Import节点后添加如下代码: <Target Name"AfterResolveReferences"><ItemGroup><EmbeddedResource Include"(ReferenceCopyLocalPaths)" Condit…...
2024年AI+游戏赛道的公司和工具归类总结
随着人工智能技术的飞速发展,AI在游戏开发领域的应用越来越广泛。以下是对2024年AI+游戏赛道的公司和工具的归类总结,涵盖了从角色和场景设计到音频制作,再到动作捕捉和动画生成等多个方面。 2D与3D创作 2D创作工具:专注于角色和场景的平面设计,提供AI辅助的图案生成和风…...
svm和决策树基本知识以及模型评价以及模型保存
svm和决策树基本知识以及模型评价以及模型保存 文章目录 一、SVM1.1,常用属性函数 二、决策树2.1,常用属性函数2.2,决策树可视化2.3,决策树解释 3,模型评价3.1,方面一(评价指标)3.2&…...
C++ 79 之 自己写异常类
#include <iostream> #include <string> using namespace std;class MyOutOfRange : public exception{ // 选中exception右键 转到定义 复制一份 virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW 进行函数重写 public: string m_msg;M…...
如何搭建一个成功的短剧制作平台
要搭建一个成功的短剧制作平台,需要考虑多个方面,包括目标定位、技术选择、内容管理、用户体验等。 1、明确目标和定位: 确定你的目标受众是谁,他们的年龄、兴趣、消费习惯等。 明确短剧制作平台的主要定位,是提供原创…...
kotlin类
一、定义 1、kotlin中使用关键字class 声明类,如果一个类没有类体,也可以省略花括号, 默认为public 类型的: // 这段代码定义了一个公开的、不可被继承的Test类 class Test{} // 没有类体,可以省略花括号 class Test 底层代码&…...
android | studio的UI布局和代码调试 | UI调试 (用于找到项目源码)
网上找到一个项目,想快速的搞懂是怎么实现的,搞了半天发现原来android都升级到Jetpack Compose了,然后去找源码挺不容易的,摸索中发现了这个调试的方法,还可以。 https://developer.android.com/studio/debug/layout-i…...
LangChain实战技巧之六:一起玩转config(上篇)——ConfigurableField
简介 Config 包含两大类内容, ConfigurableField 可配置的字段 configurable_alternatives 可配置的替代方案 分别使用两篇文章来给大家介绍,本篇先介绍ConfigurableField 常规介绍 一些资料会这样介绍 model_spec model.configurable_fields(model…...
扫码称重上位机
目录 一 设计原型 二 后台代码 一 设计原型 模拟工具: 二 后台代码 主程序: using System.IO.Ports; using System.Net; using System.Net.Sockets; using System.Text;namespace 扫码称重上位机 {public partial class Form1 : Form{public Form1(){Initialize…...
操作系统入门 -- 进程的通信方式
操作系统入门 – 进程的通信方式 1.什么是进程通信 1.1 定义 进程通信就是在不同进程之间交换信息。在之前文章中可以了解到,进程之间相互独立,一般不可能互相访问。因此进程之间若需要通信,则需要一个所有进程都认可的共享空间࿰…...
Python读取wps中的DISPIMG图片格式
需求: 读出excel的图片内容,这放在微软三件套是很容易的,但是由于wps的固有格式,会出现奇怪的问题,只能读出:类似于 DISPIMG(“ID_2B83F9717AE1XXXX920xxxx644C80DB1”,1) 【该DISPIMG函数只有wps才拥有】 …...
elasticsearch的入门与实践
Elasticsearch是一个基于Lucene构建的开源搜索引擎。它提供了一个分布式、多租户能力的全文搜索引擎,具有HTTP web接口和无模式的JSON文档。以下是Elasticsearch的入门与实践的基本步骤: 入门 安装Elasticsearch: 从Elasticsearch官网下载对…...
神经网络学习6-线性层
归一化用的较少 正则化用来解决过拟合,处理最优化问题,批量归一化加快速度 正则化(Regularization): 作用:正则化是一种用来防止过拟合的技术,通过向模型的损失函数中添加惩罚项,使…...
PHP框架详解 - CodeIgniter 框架
CodeIgniter 是一个成熟的轻量级 PHP 框架,专为小到中型的 Web 应用开发设计。它以其简洁、灵活和易于学习的特点而受到开发者的喜爱。 CodeIgniter 框架的特点包括: 轻量级:CodeIgniter 的核心非常小,加载速度快,适…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
