当前位置: 首页 > news >正文

双例集合(三)——双例集合的实现类之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接口有两个实现类&#xff0c;一个是HashMap容器类&#xff0c;另一个是TreeMap容器类。TreeMap容器类的使用在API上于HashMap容器类没有太大的区别。它们的区别主要体现在两个方面&#xff0c;一个是底层实现方式上&#xff0c;HashMap是基于Hash算法来实现的吗&#xff0c…...

[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

主函数&#xff1a; #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万

“辛辛苦苦攒了几年钱&#xff0c;本想买房买车&#xff0c;结果全被老婆炒股亏掉了&#xff01;” 近日&#xff0c;一位30岁的程序员大哥在网上吐苦水&#xff0c;引发了网友们的热议。 这位程序员大哥和妻子结婚后&#xff0c;一直秉持着“男主外&#xff0c;女主内”的传统…...

Docker常见面试题整理

文章目录 1. Docker 是什么&#xff1f;它解决了什么问题&#xff1f;2. Docker 和虚拟机&#xff08;VM&#xff09;的区别是什么&#xff1f;3、Docker三个核心概念4、如何构建一个 Docker 镜像&#xff1f;5、如何将一个 Docker 容器连接到多个网络&#xff1f;6、Docker Co…...

35 - 最后一个能进入巴士的人(高频 SQL 50 题基础版)

35 - 最后一个能进入巴士的人 -- sum(weight) over(order by turn) as total,根据turn升序&#xff0c;再求前面数的和 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文件中 第一步&#xff1a;打开.csproj文件&#xff0c;在Import节点后添加如下代码&#xff1a; <Target Name"AfterResolveReferences"><ItemGroup><EmbeddedResource Include"(ReferenceCopyLocalPaths)" Condit…...

2024年AI+游戏赛道的公司和工具归类总结

随着人工智能技术的飞速发展,AI在游戏开发领域的应用越来越广泛。以下是对2024年AI+游戏赛道的公司和工具的归类总结,涵盖了从角色和场景设计到音频制作,再到动作捕捉和动画生成等多个方面。 2D与3D创作 2D创作工具:专注于角色和场景的平面设计,提供AI辅助的图案生成和风…...

svm和决策树基本知识以及模型评价以及模型保存

svm和决策树基本知识以及模型评价以及模型保存 文章目录 一、SVM1.1&#xff0c;常用属性函数 二、决策树2.1&#xff0c;常用属性函数2.2&#xff0c;决策树可视化2.3&#xff0c;决策树解释 3&#xff0c;模型评价3.1&#xff0c;方面一&#xff08;评价指标&#xff09;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…...

如何搭建一个成功的短剧制作平台

要搭建一个成功的短剧制作平台&#xff0c;需要考虑多个方面&#xff0c;包括目标定位、技术选择、内容管理、用户体验等。 1、明确目标和定位&#xff1a; 确定你的目标受众是谁&#xff0c;他们的年龄、兴趣、消费习惯等。 明确短剧制作平台的主要定位&#xff0c;是提供原创…...

kotlin类

一、定义 1、kotlin中使用关键字class 声明类,如果一个类没有类体&#xff0c;也可以省略花括号&#xff0c; 默认为public 类型的&#xff1a; // 这段代码定义了一个公开的、不可被继承的Test类 class Test{} // 没有类体&#xff0c;可以省略花括号 class Test 底层代码&…...

android | studio的UI布局和代码调试 | UI调试 (用于找到项目源码)

网上找到一个项目&#xff0c;想快速的搞懂是怎么实现的&#xff0c;搞了半天发现原来android都升级到Jetpack Compose了&#xff0c;然后去找源码挺不容易的&#xff0c;摸索中发现了这个调试的方法&#xff0c;还可以。 https://developer.android.com/studio/debug/layout-i…...

LangChain实战技巧之六:一起玩转config(上篇)——ConfigurableField

简介 Config 包含两大类内容&#xff0c; ConfigurableField 可配置的字段 configurable_alternatives 可配置的替代方案 分别使用两篇文章来给大家介绍&#xff0c;本篇先介绍ConfigurableField 常规介绍 一些资料会这样介绍 model_spec model.configurable_fields(model…...

扫码称重上位机

目录 一 设计原型 二 后台代码 一 设计原型 模拟工具: 二 后台代码 主程序&#xff1a; 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 定义 进程通信就是在不同进程之间交换信息。在之前文章中可以了解到&#xff0c;进程之间相互独立&#xff0c;一般不可能互相访问。因此进程之间若需要通信&#xff0c;则需要一个所有进程都认可的共享空间&#xff0…...

Python读取wps中的DISPIMG图片格式

需求&#xff1a; 读出excel的图片内容&#xff0c;这放在微软三件套是很容易的&#xff0c;但是由于wps的固有格式&#xff0c;会出现奇怪的问题&#xff0c;只能读出&#xff1a;类似于 DISPIMG(“ID_2B83F9717AE1XXXX920xxxx644C80DB1”,1) 【该DISPIMG函数只有wps才拥有】 …...

elasticsearch的入门与实践

Elasticsearch是一个基于Lucene构建的开源搜索引擎。它提供了一个分布式、多租户能力的全文搜索引擎&#xff0c;具有HTTP web接口和无模式的JSON文档。以下是Elasticsearch的入门与实践的基本步骤&#xff1a; 入门 安装Elasticsearch&#xff1a; 从Elasticsearch官网下载对…...

神经网络学习6-线性层

归一化用的较少 正则化用来解决过拟合&#xff0c;处理最优化问题&#xff0c;批量归一化加快速度 正则化&#xff08;Regularization&#xff09;&#xff1a; 作用&#xff1a;正则化是一种用来防止过拟合的技术&#xff0c;通过向模型的损失函数中添加惩罚项&#xff0c;使…...

PHP框架详解 - CodeIgniter 框架

CodeIgniter 是一个成熟的轻量级 PHP 框架&#xff0c;专为小到中型的 Web 应用开发设计。它以其简洁、灵活和易于学习的特点而受到开发者的喜爱。 CodeIgniter 框架的特点包括&#xff1a; 轻量级&#xff1a;CodeIgniter 的核心非常小&#xff0c;加载速度快&#xff0c;适…...

发掘Python之魂:探索数据结构与算法的宝典

发掘Python之魂&#xff1a;探索数据结构与算法的宝典 【下载地址】Python数据结构与算法教程及代码 本资源文件《Python数据结构与算法教程及代码》是一份精心整理的教程&#xff0c;旨在帮助学习者深入理解Python中的数据结构与算法。算法&#xff08;Algorithm&#xff09;是…...

【免费下载】 新魔百和M301H-CW代工系列强刷固件:当贝桌面纯净版安卓系统

新魔百和M301H-CW代工系列强刷固件&#xff1a;当贝桌面纯净版安卓系统 【下载地址】16-001-T-新魔百和M301H-CW代工-Hi3798MV300-MV310通用强刷固件当贝桌面纯净版安卓系统 本资源包专为新魔百和M301H-CW代工系列设备设计&#xff0c;适用于Hi3798MV300和MV310芯片组的智能电视…...

VSCode里PlatformIO插件抽风?手把手教你彻底卸载重装PIO(解决创建工程失败)

VSCode PlatformIO插件异常终极解决手册&#xff1a;从崩溃到重生的全流程指南 当你在VSCode中满怀期待地点击"New Project"按钮&#xff0c;却看到那个刺眼的红色错误提示时&#xff0c;那种挫败感每个开发者都懂。PlatformIO作为物联网开发的瑞士军刀&#xff0c;一…...

Windows Subsystem for Android终极指南:5大核心优势与完整开发实战

Windows Subsystem for Android终极指南&#xff1a;5大核心优势与完整开发实战 【免费下载链接】WSA Developer-related issues and feature requests for Windows Subsystem for Android 项目地址: https://gitcode.com/gh_mirrors/ws/WSA Windows Subsystem for Andr…...

在 Elasticsearch 中使用带有确定性护栏的 Agentic AI 搜索,以实现安全的查询执行

作者&#xff1a;来自 Elastic Alexander Marquardt, Honza Krl 及 Taylor Roy 当 LLM 直接生成查询时&#xff0c; Agentic AI 搜索系统通常会失败。了解确定性护栏和控制平面架构如何通过 Elasticsearch 实现安全、可靠且受治理的查询执行。 刚接触 Elasticsearch&#xff1…...

算力基石:CPU、GPU与嵌入式AI的技术逻辑与融合发展

在人工智能全面普及的时代&#xff0c;算力已经成为数字产业发展的核心驱动力。从日常使用的智能手机、家用电脑&#xff0c;到云端大模型、智能汽车、工业传感设备&#xff0c;各类智能终端的运转都离不开处理器的算力支撑。其中&#xff0c;CPU作为通用计算核心、GPU作为并行…...

西安给孩子配镜哪个公司口碑好

如果在西安想给孩子配镜&#xff0c;甲目眼镜&#xff08;成都&#xff09;有限公司是个不错的选择。甲目眼镜聚焦中高端写字楼白领与商务人群&#xff0c;同时也为孩子配镜提供优质服务。它以“高性价比的高端眼镜”为使命&#xff0c;严选国内外一线品牌&#xff0c;重塑了品…...

ARM SVE2饱和运算指令SQSHRNB与SQSHRUNB详解

1. ARM SVE2指令集概述ARM的可伸缩向量扩展第二版(SVE2)是NEON指令集的下一代演进&#xff0c;为高性能计算和机器学习工作负载提供了更强大的向量处理能力。与传统的SIMD指令集不同&#xff0c;SVE2引入了多项创新特性&#xff1a;可变向量长度(VLA)&#xff1a;程序员无需针对…...

从“上管掉电”到稳定驱动:手把手教你计算EG2104自举电容的容值与选型(附PWM占空比影响分析)

从“上管掉电”到稳定驱动&#xff1a;手把手教你计算EG2104自举电容的容值与选型&#xff08;附PWM占空比影响分析&#xff09; 在高压半桥驱动电路设计中&#xff0c;自举电容的选型往往成为工程师最易忽视却最关键的环节。EG2104作为一款经典的高低压侧驱动芯片&#xff0c;…...

OneNote 2016/2019/2021多版本共存?教你管理不同版本的笔记同步与数据源

OneNote多版本共存管理&#xff1a;数据同步与版本控制的终极指南 在数字笔记领域&#xff0c;微软OneNote凭借其灵活的层级结构和多平台同步能力&#xff0c;成为许多知识工作者的核心工具。但鲜为人知的是&#xff0c;当同一台设备上同时运行多个OneNote版本&#xff08;如UW…...