【集合系列】TreeMap 集合

TreeMap 集合

    • 1. 概述
    • 2. 方法
    • 3. 遍历方式
    • 4. 排序方式
    • 5. 代码示例1
    • 6. 代码示例2
    • 7. 代码示例3
    • 8. 注意事项

其他集合类

父类 Map

集合类的遍历方式

TreeSet 集合

具体信息请查看 API 帮助文档

1. 概述

TreeMap 是 Java 中的一个集合类,它实现了 SortedMap 接口。它是基于红黑树的数据结构实现的,它能够保持其中的元素处于有序状态。

  • TreeMap 集合中的元素是以键值对的形式存储的,其中的键用于排序和唯一性的保证,而值则用于存储具体的数据。

  • TreeMap 根据键的自然顺序或者自定义的比较器来进行排序,使得在遍历 TreeMap 集合时能够有序地访问其中的元素。

TreeMap 集合的特点

  1. TreeMap 中的键必须是可比较的,要么实现了 Comparable 接口,要么在构造 TreeMap 时提供了自定义的比较器。

  2. TreeMap 中的键是唯一的,不允许重复的键存在。

  3. TreeMap 是基于红黑树实现的,因此在插入、删除和查找操作的时间复杂度均为 O(logn),具有较高的效率。

  4. TreeMap 中的元素是有序的,可以根据键来进行排序。

  5. TreeMap 不是线程安全的,如果需要在多线程环境下使用,需要进行额外的同步处理。

2. 方法

TreeMap集合是Map集合的子类,因此Map集合的方法TreeMap集合都能使用。

Map集合

方法名说明
V put(K key,V value)添加元素
V remove(Object key)根据键删除键值对元素
void clear()移除所有的键值对元素
boolean containsKey(Object key)判断集合是否包含指定的键
boolean containsValue(Object value)判断集合是否包含指定的值
boolean isEmpty()判断集合是否为空
int size()集合的长度,也就是集合中键值对的个数

3. 遍历方式

与共有的 集合遍历方式 一样

4. 排序方式

TreeMap集合和TreeSet集合一样,底层都是红黑树,因此排序方式一样

TreeSet 集合排序方式详解

  • 默认排序规则/自然排序

  • 比较器排序

5. 代码示例1

  • 代码示例
    需求:键:整数表示id;值:字符串表示商品名称
    要求:按照id的升序排列,按照id的降序排列
package text.text02;
/*TreeMap基本应用:
需求:键:整数表示id值:字符串表示商品名称
要求:按照id的升序排列,按照id的降序排列
*/import java.util.Comparator;
import java.util.TreeMap;public class text52 {public static void main(String[] args) {//自然排序(升序排列)System.out.println("方法一:自然排序");method1();        //{1001=平板, 1002=汽车, 1003=手机, 1004=飞机, 1005=电脑}//比较器排序(降序排列)System.out.println("方法二:比较器排序");method2();        //{1005=电脑, 1004=飞机, 1003=手机, 1002=汽车, 1001=平板}}//自然排序(Java底层默认的自然排序就是按照升序排列)public static void method1() {//创建集合并添加数据TreeMap<Integer, String> tm = new TreeMap<>();tm.put(1003, "手机");tm.put(1005, "电脑");tm.put(1001, "平板");tm.put(1002, "汽车");tm.put(1004, "飞机");System.out.println(tm);}//比较器排序(当Java底层默认的自然排列不能满足需求时,采用比较器排列)public static void method2() {//创建集合(在创建对象的时候指定比较器规则)TreeMap<Integer, String> tm = new TreeMap<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1;}});//添加数据tm.put(1003, "手机");tm.put(1005, "电脑");tm.put(1001, "平板");tm.put(1002, "汽车");tm.put(1004, "飞机");System.out.println(tm);}
}
  • 输出结果
    • 方法一:自然排序
      在这里插入图片描述

    • 方法二:比较器排序
      在这里插入图片描述

6. 代码示例2

  • 代码示例
    需求:键:学生对象;值:籍贯
    要求:按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名同年龄视为同一个人
package text.text02;import java.util.*;/*
需求:键:学生对象值:籍贯
要求:按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名同年龄视为同一个人*/
public class text53 {public static void main(String[] args) {//自然排序System.out.println("方法一:自然排序");method1();//比较器排序System.out.println("方法二:比较器排序");method2();}//自然排序 (Java底层默认的自然排序就是按照升序排列,自定义对象时,需要在Javabean类中实现Comparable接口并重写里面的CompareTo方法)public static void method1() {//创建学生对象Student8 student1 = new Student8("zhangsan", 10);Student8 student2 = new Student8("lisi", 10);Student8 student3 = new Student8("wangwu", 11);Student8 student4 = new Student8("liubei", 9);Student8 student5 = new Student8("guanyu", 13);Student8 student6 = new Student8("guanyu", 13);//创建集合对象TreeMap<Student8, String> tm = new TreeMap<>();//添加数据tm.put(student1, "陕西");tm.put(student2, "湖南");tm.put(student3, "河北");tm.put(student4, "江苏");tm.put(student5, "北京");tm.put(student6, "湖南");//遍历输出集合Set<Map.Entry<Student8, String>> entries = tm.entrySet();for (Map.Entry<Student8, String> entry : entries) {Student8 key = entry.getKey();String value = entry.getValue();System.out.println(key + " = " + value);}}//比较器排序(当Java底层默认的自然排列不能满足需求时,采用比较器排列,在创建对象时,指定比较规则)public static void method2() {//创建学生对象Student8 student1 = new Student8("zhangsan", 10);Student8 student2 = new Student8("lisi", 10);Student8 student3 = new Student8("wangwu", 11);Student8 student4 = new Student8("liubei", 9);Student8 student5 = new Student8("guanyu", 13);Student8 student6 = new Student8("guanyu", 13);//创建集合对象TreeMap<Student8, String> tm = new TreeMap<>(new Comparator<Student8>() {@Override//按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名同年龄视为同一个人public int compare(Student8 o1, Student8 o2) {//o1:表示当前要添加的元素//o2:表示已经在红黑树存在的元素//返回值://负数:表示当前要添加的数据是小的,存左边//正数:表示当前要添加的数据是大的,存右边//0:表示当前要添加的元素已经存在,舍弃int i = o1.getAge() - o2.getAge();i = i == 0 ? o1.getName().compareTo(o2.getName()) : i;return i;}});//添加数据tm.put(student1, "陕西");tm.put(student2, "湖南");tm.put(student3, "河北");tm.put(student4, "江苏");tm.put(student5, "北京");tm.put(student6, "湖南");//遍历输出集合Set<Map.Entry<Student8, String>> entries = tm.entrySet();for (Map.Entry<Student8, String> entry : entries) {Student8 key = entry.getKey();String value = entry.getValue();System.out.println(key + " = " + value);}}
}//学生对象
class Student8 implements Comparable<Student8> {private String name;private int age;public Student8() {}public Student8(String name, int age) {this.name = name;this.age = age;}/*** 获取** @return name*/public String getName() {return name;}/*** 设置** @param name*/public void setName(String name) {this.name = name;}/*** 获取** @return age*/public int getAge() {return age;}/*** 设置** @param age*/public void setAge(int age) {this.age = age;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student8 student8 = (Student8) o;return age == student8.age && Objects.equals(name, student8.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}public String toString() {return "Student8{name = " + name + ", age = " + age + "}";}@Override//按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名同年龄视为同一个人public int compareTo(Student8 o) {//this:表示当前要添加的元素//o:表示已经在红黑树中的元素//返回值://负数:表示当前要添加的数据是小的,存左边//正数:表示当前要添加的数据是大的,存右边//0:表示当前要添加的元素已经存在,舍弃int i = this.getAge() - o.getAge();i = i == 0 ? this.getName().compareTo(o.getName()) : i;return i;}
}
  • 输出结果
    • 方法一:自然排序
      在这里插入图片描述

    • 方法二:比较器排序
      在这里插入图片描述

7. 代码示例3

  • 代码示例
    统计个数:
    需求:字符串“aababcabcdabcde”,请统计字符串中每一个字符出现的次数,并按照如下格式输出。
    输出结果:a(5)b(4)c(3)d(2)e(1)
package text.text02;import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import java.util.TreeMap;/*
统计个数:
需求:字符串“aababcabcdabcde”,请统计字符串中每一个字符出现的次数,并按照如下格式输出。输出结果:a(5)b(4)c(3)d(2)e(1)新的统计思想:利用Map集合进行统计      (键:表示要统计的内容;值:表示次数)如果题目中没有要求对结果进行排序,默认使用HashMap如果题目中要求对结果进行排序,则使用TreeMap*/
public class text54 {public static void main(String[] args) {//创建数组存储每一个字符char[] arr = {'a', 'b', 'c', 'd', 'e'};//定义一个变量用于记录字符串String str = "aababcabcdabcde";//创建集合TreeMap<Character, Integer> tm = new TreeMap<>();for (int i = 0; i < str.length(); i++) {//如果双列集合中存在该字符,则获取双列集合中该字符的次数并将次数+1if (tm.containsKey(str.charAt(i))) {//获取双列集合中该字符的次数Integer value = tm.get(str.charAt(i));//将次数+1value++;//用新次数覆盖原次数tm.put(str.charAt(i), value);}//如果双列集合中存在该字符,则添加该字符并将次数改为1else {tm.put(str.charAt(i), 1);}}//遍历集合//1.利用StringBuilder修改输出格式//创建StringBuilder对象StringBuilder sb = new StringBuilder();Set<Map.Entry<Character, Integer>> entries = tm.entrySet();for (Map.Entry<Character, Integer> entry : entries) {//获取集合里的键Character key = entry.getKey();//获取集合里的值Integer value = entry.getValue();//将数据按照需求格式添加进StringBuilder集合sb.append(key).append("(").append(value).append(")");}System.out.println("1.利用StringBuilder修改输出格式:");System.out.println(sb);                  //a(5)b(4)c(3)d(2)e(1)//2.利用StringJoiner修改输出格式//创建StringJoiner对象StringJoiner sj = new StringJoiner("", "", "");Set<Character> set = tm.keySet();for (Character key : set) {Integer value = tm.get(key);//将数据按照需求格式添加进StringJoiner集合sj.add(key + "").add("(").add(value + "").add(")");//+" "是为了将key和value转换成字符串}System.out.println("2.利用StringJoiner修改输出格式:");System.out.println(sj);       //a(5)b(4)c(3)d(2)e(1)}
}
  • 输出结果
    • 1.利用StringBuilder修改输出格式:
      在这里插入图片描述

    • 2.利用StringJoiner修改输出格式:
      在这里插入图片描述

8. 注意事项

  1. 键的唯一性:TreeMap 中的键是唯一的,不允许重复的键存在。如果尝试插入一个已经存在的键,新的值将会覆盖旧的值。如果需要存储允许重复键的情况,可以考虑使用其他集合类如 ArrayList 或者 HashMap。

  2. 键的可比较性:TreeMap 要求集合中的键必须是可比较的,要么实现了 Comparable 接口,要么在构造 TreeMap 时提供了自定义的比较器。如果键没有实现 Comparable 接口,并且没有提供自定义的比较器,则在插入元素或者进行比较操作时会抛出 ClassCastException 异常。

  3. 线程安全性:TreeMap 不是线程安全的,如果需要在多线程环境下使用 TreeMap,需要进行额外的同步处理。可以考虑使用 Collections 类的 synchronizedSortedMap 方法包装 TreeMap,或者使用并发集合类如 ConcurrentHashMap。

  4. 迭代顺序:TreeMap 中的元素是有序的,可以根据键来进行排序。通过 iterator 或者 forEach 遍历 TreeMap 时,元素会按照键的顺序以升序进行遍历。

  5. 性能开销:由于 TreeMap 的底层是红黑树,插入、删除和查找操作的时间复杂度均为 O(logn),相比于其他集合类可能会有较高的性能开销。如果对性能有较高要求,可以考虑使用其他集合类。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

抽象springBoot报错

Failed to configure a DataSource: url attribute is not specified and no embedded datasource could be configured. 中文翻译&#xff1a;无法配置DataSource&#xff1a;未指定“url”属性&#xff0c;并且无法配置嵌入数据源。 DataSource 翻译&#xff1a;数据源 得…

MMOARPG网络战斗系统二期

哈喽&#xff0c;大家好&#xff0c;我叫人宅&#xff0c;很高兴介绍一下本期的MMOARPG课程。 我们的mmoarpg是一套商业级别的分布式服务器框架 SNCDS这套方案。我们公司也采用的是这套框架&#xff0c;代码量已经近二十万行&#xff0c;目前还在研发。 这么多代码如果都详细演…

前端ajax技术

ajax可以实现局部刷新&#xff0c;也叫做无刷新&#xff0c;无刷新指的是整个页面不刷新&#xff0c;只是局部刷新&#xff0c;ajax可以自己发送http请求&#xff0c;不用通过浏览器的地址栏&#xff0c;所以页面整体不会刷新&#xff0c;ajax获取到后台数据&#xff0c;更新页…

kettle控件-复制记录到结果/ 从结果获取记录的使用

在数据采集过程中&#xff0c;遇到对方数据传送不及时的情况&#xff0c;导致数据漏采集&#xff0c;需要手工反复补采。为了解决这一问题&#xff0c;可以利用kettle的复制记录到结果/从结果获取记录控件。 job的整个流程如下&#xff1a; 设置变量&#xff1a; 创建目录: ge…

TCP的连接和断开详解

目录 1.TCP基础知识 1.1.TCP 头格式 1.2.TCP协议介绍 1.3.UDP协议介绍 1.4.TCP 和 UDP 区别 1.5.TCP 和 UDP 应用场景 1.6.计算机网络相关术语&#xff08;缩写&#xff09; 2.TCP 连接建立&#xff1a;三次握手 2.1.TCP 三次握手过程 2.2.三次握手原理 2.3.异常分析…

猫头虎分享:什么是IDE?新手入门用哪个IDE比较好?

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

【模板初阶】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 1. 泛型编程 2. 函数模板 2.1 函数模板概念 2.2 函数模板格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 3. 类模板 3.1 类模板的定义…

【VTKExamples::PolyData】第二十三期 InterpolateMeshOnGrid

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享VTK样例InterpolateMeshOnGrid,并解析接口vtkProbeFilter 、vtkWarpScalar & vtkDealuany2D等多个接口,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!…

c语言--一维数组传参的本质(详解)

目录 一、前言二、代码三、形式3.1形式13.2形式2 四、总结 一、前言 首先从⼀个问题开始&#xff0c;我们之前都是在函数外部计算数组的元素个数&#xff0c;那我们可以把函数传给⼀个函数后&#xff0c;函数内部求数组的元素个数吗&#xff1f; 二、代码 直接上代码&#x…

笔记---dp---数字三角形模型

所谓数字三角形模型&#xff0c;即是从数字三角形这一题衍生出来的 题目为经典题目&#xff0c;不再赘述&#xff0c;此笔记根据AcWing算法提高课来进行对数字三角形模型衍生例题的记录 题目关系如下&#xff08;见AcWing里的AcSaber&#xff09;&#xff1a; AcWing.1015.摘…

使用深度学习对视频进行分类

目录 加载预训练卷积网络 加载数据 将帧转换为特征向量 准备训练数据 创建 LSTM 网络 指定训练选项 训练 LSTM 网络 组合视频分类网络 使用新数据进行分类 辅助函数 此示例说明如何通过将预训练图像分类模型和 LSTM 网络相结合来创建视频分类网络。 要为视频…

openGauss学习笔记-216 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-CPU

文章目录 openGauss学习笔记-216 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-CPU216.1 CPU216.2 查看CPU状况216.3 性能参数分析 openGauss学习笔记-216 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-CPU 获取openGauss节点的CPU、内存、I/O和网络资源使用情况…