深入理解Java TreeSet:实现与使用案例分析

news2024/10/6 12:22:57

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  在Java中,有很多常用的数据结构,例如List、Set、Map等,这些数据结构都是为了方便程序员的数据管理而存在的。而TreeSet作为Set的一种实现方式,它的底层实现是基于红黑树的。

摘要

  本文将对Java中的TreeSet进行详细介绍,包括其底层实现原理、应用场景案例、优缺点分析、类代码方法介绍、以及测试用例等内容,旨在帮助读者更好地了解和使用TreeSet。

TreeSet类

简介

  TreeSet是Java中的一个基于红黑树实现的有序集合,它实现了NavigableSet接口和SortedSet接口。与HashSet不同,TreeSet中的元素是有序的,且不允许存在重复元素。在TreeSet中,元素按照指定顺序进行存储,并且可以在O(log(n))时间复杂度内实现插入、查找、删除等操作。TreeSet可以对元素进行自然排序或者指定排序方式。

源代码解析

  TreeSet的底层实现是基于红黑树的,红黑树是一种自平衡的二叉搜索树。红黑树的每个节点都具有一个颜色属性,为红色或黑色。在插入与删除节点的过程中,通过改变颜色和旋转节点来保持红黑树的平衡。红黑树的所有操作都可以在O(log(n))时间复杂度内完成。

  TreeSet中的add()方法实现了对元素的插入操作,它首先调用红黑树的插入方法,在插入节点时会进行颜色调整和旋转操作,保持红黑树的平衡性。TreeSet中的remove()方法实现了对元素的删除操作,也会进行颜色调整和旋转操作来保持红黑树的平衡。

  如下是Java TreeSet 是一种基于红黑树实现的集合,具有以下特点:

1.元素自动排序:TreeSet 中的元素会自动按照其自然顺序进行排序;或者按照构造 TreeSet 时传入的 Comparator 进行排序。

  1. 线程不安全:TreeSet 并不是线程安全的。

  2. 支持高效的插入、删除、查找操作:由于底层是基于红黑树实现,因此这些操作的时间复杂度为 O(logN)。

下面,我们来看一下 TreeSet 的源代码实现。

  1. 数据结构

TreeSet 的底层实现是一个基于 TreeMap 的映射,其中键就是 TreeSet 中的元素,值则是一个固定的 Object 对象。因为 TreeMap 是基于红黑树实现的,所以 TreeSet 中的元素也具有自动排序的特点。

  1. 构造函数

TreeSet 有多个构造函数,其中最常用的是无参构造函数和一个 Comparator 类型的参数构造函数。

无参构造函数:

public TreeSet() {
    this(new TreeMap<>());
}

该构造函数会新建一个基于 TreeMap 的映射。

带 Comparator 参数的构造函数:

public TreeSet(Comparator<? super E> comparator) {
    this(new TreeMap<>(comparator));
}

该构造函数会新建一个基于 TreeMap 的映射,并且使用传入的 Comparator 进行元素排序。

  1. 插入元素

TreeSet 的插入元素操作是基于 TreeMap 的 put() 方法实现的,具体实现代码如下:

public boolean add(E e) {
    return m.put(e, PRESENT)==null;
}

其中,PRESENT 是一个固定的 Object 对象,用于作为 TreeMap 的 value。

当插入一个新元素时,如果 TreeMap 中已经存在相同的元素,则会更新该元素的 value 值,并且返回 false;否则,将新元素插入到 TreeMap 中,并且返回 true。

  1. 删除元素

TreeSet 的删除元素操作也是基于 TreeMap 的 remove() 方法实现的,具体实现代码如下:

public boolean remove(Object o) {
    return m.remove(o)==PRESENT;
}

该方法会将 TreeMap 中键为 o 的元素删除,并且返回该元素对应的 value 值。如果该 value 值为 PRESENT,则表示 TreeMap 中原来确实存在这个元素,删除该元素成功,并且返回 true;否则返回 false。

  1. 遍历元素

TreeSet 提供了多种遍历元素的方式,包括迭代器、forEach() 方法等。其中, 迭代器遍历的顺序是按照元素的自然顺序或者 Comparator 的顺序进行的。

源代码部分截图:

在这里插入图片描述

  总之,Java TreeSet 是一个基于红黑树实现的集合,具有元素自动排序、线程不安全、支持高效的插入、删除、查找等操作的特点。在实现过程中,TreeSet 底层是基于 TreeMap 进行数据存储与操作的。如果需要存储有序的元素,或者进行快速的插入、删除、查找等操作,可以使用 Java TreeSet。

应用场景案例

  TreeSet的有序性和快速查找的特点使得它在很多场景下都可以发挥重要作用,例如:

  1. 排序数据:TreeSet可以对元素进行自然排序或者指定排序方式,因此可以非常方便地对数据进行排序操作。
  2. 去重数据:TreeSet中不允许存在重复元素,因此可以用来去重。
  3. 优先级队列:TreeSet可以实现一个优先级队列,在优先级队列中,元素按照指定顺序进行存储,并且可以在O(log(n))时间复杂度内实现插入、查找、删除等操作。

优缺点分析

TreeSet作为一种基于红黑树实现的有序集合,具有以下优缺点:

优点

  1. 元素有序:TreeSet中的元素是有序的,可以进行自然排序或者指定排序方式。
  2. 快速查找:在TreeSet中进行查找操作的时间复杂度为O(log(n)),因此查找速度非常快。
  3. 去重数据:TreeSet中不允许存在重复元素,可以用来去重。

缺点

  1. 空间开销大:TreeSet的底层实现是基于红黑树的,因此需要额外的空间存储树的结构,导致空间开销较大。
  2. 插入、删除操作慢:虽然在TreeSet中进行查找操作的时间复杂度为O(log(n)),但是插入、删除操作的时间复杂度也是O(log(n)),因此在频繁进行插入、删除操作时,性能可能不如HashSet等数据结构。

类代码方法介绍

方法一:add()

public boolean add(E e)

方法说明:

向TreeSet中添加一个元素。

参数说明:

  • e:要添加的元素。

返回值:

  • 如果插入成功返回true,否则返回false。

方法二:remove()

public boolean remove(Object o)

方法说明:

TreeSet中删除指定元素。

参数说明:

  • o:要删除的元素。

返回值:

  • 如果删除成功返回true,否则返回false。

方法三:iterator()

public Iterator<E> iterator()

方法说明:

返回一个迭代器,用于遍历TreeSet中的元素。

返回值:

  • 返回一个迭代器,用于遍历TreeSet中的元素。

测试用例

用例代码

如下通过使用TreeSet来给大家做个演示:代码如下:

package com.example.javase.collection;

import java.util.Iterator;
import java.util.TreeSet;

/**
 * @Author ms
 * @Date 2023-10-24 21:23
 */
public class TreeSetTest {

    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<>();

        // 添加元素
        set.add("apple");
        set.add("banana");
        set.add("orange");
        set.add("pear");
        set.add("grape");
        set.add("watermelon");

        // 输出元素
        System.out.println("TreeSet中的元素为:");
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
        System.out.println();

        // 删除元素
        set.remove("orange");

        // 输出元素
        System.out.println("删除元素后,TreeSet中的元素为:");
        iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
        System.out.println();
    }
}

测试结果

输出结果:

TreeSet中的元素为:
apple banana grape orange pear watermelon 
删除元素后,TreeSet中的元素为:
apple banana grape pear watermelon 

结果截图如下:

在这里插入图片描述

测试代码分析

  这段代码演示了如何使用Java中的TreeSet类,实现了向集合中添加元素、输出元素、删除元素等基本操作。

  首先,创建了一个String类型的TreeSet对象set,并向其中添加了多个元素,即"apple"、“banana”、“orange”、“pear”、“grape”、“watermelon”。

  然后,利用迭代器遍历输出set中的元素,其中利用了hasNext()next()方法。

  接着,从set中删除了一个元素"orange"。

  最后,再次利用迭代器遍历输出set中的元素,查看删除操作是否生效。

全文小结

  本文主要介绍了Java中的TreeSet,包括其底层实现原理、应用场景案例、优缺点分析、方法介绍以及测试用例等内容。通过本文的阅读,读者可以更好地了解并使用TreeSet。

总结

  本文主要介绍了Java中的TreeSet类,包括其底层实现原理、应用场景案例、优缺点分析、方法介绍以及测试用例等内容。通过本文的介绍,我们了解到TreeSet是一种基于红黑树实现的有序集合,具有元素有序、快速查找、去重数据等优点,可以应用到很多场景中。但是,由于TreeSet的底层实现是基于红黑树的,因此在插入、删除操作上可能不如HashSet等数据结构。因此,在使用TreeSet时,需要根据具体场景来选择。

  本文还通过测试用例的方式,演示了如何使用Java中的TreeSet类,实现了向集合中添加元素、输出元素、删除元素等基本操作。通过测试代码的分析,读者可以更好地了解使用TreeSet的具体方法。

  综上所述,通过本文的阅读,读者可以更好地了解并使用TreeSet,从而提高Java编程的效率和质量。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

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

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

相关文章

【WPF学习笔记(一)】WPF应用程序的组成及Window类介绍

WPF应用程序的组成及Window类介绍 WPF应用程序的组成及Window类介绍前言正文1、WPF介绍1.1 什么是WPF1.2 WPF的特点1.3 WPF的控件分类 2、XAML介绍2.1 XAML的定义2.2 XAML的特点2.3 XAML的命名空间 3、WPF应用程序组成3.1 App.config3.2 App.xaml3.3 App.xaml.cs3.4 MainWindow…

react18【实战】tab切换,纯前端列表排序(含 lodash 和 classnames 的安装和使用)

技术要点 动态样式 className{tabItem ${currentType item.value && "active"}}安装 lodash npm i --save lodash使用 lodash 对对象数组排序&#xff08;不会改变源数组&#xff09; _.orderBy(dataList, "readNum", "desc")src\De…

十二种网络威胁防护方案

一、SQL注入 SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理员不知情的情况下实现非法操作&#xff0c;以此来实现欺骗数据库服务器执行非授权的任…

Python之数据分析基础

导言&#xff1a; “21世纪的竞争是数据的竞争&#xff0c;谁掌握数据&#xff0c;谁就掌握未来”。如何将大量看似杂乱无章的数据进行聚合&#xff0c;并发现潜在的规律也变得越来越重要。本文将先说明数据分析的步骤&#xff0c;再通过python完成实例数据的处理、分析最终展…

19.接口自动化-Jekins学习

1.CI-持续集成 频繁的&#xff08;一天多次&#xff09;将代码集成到主干 目的&#xff1a;让产品快速迭代&#xff0c;保持高质量 好处&#xff1a; 快速发现错误&#xff0c;每次更新都集成到主干&#xff0c;可以快速发现错误&#xff0c;定位错误也容易防止分支大幅偏离主…

示波器基础1-带宽

数字示波器最重要的基本特征之一是其带宽&#xff0c;了解带宽及其对技术指标的影响对于选择合适的示波器非常有帮助。 这里我们对示波器带宽的一些基本方面做一简要介绍。 当我们谈到示波器的带宽时&#xff0c;重要的是要区分模拟带宽和数字带宽。模拟带宽主要受仪器模拟输入…

TriCore: Architecture

说明 本文是 英飞凌 架构文档 TriCore TC162P core archiecture Volume 1 of 2 (infineon.com) 的笔记&#xff0c;稍作整理方便查阅&#xff0c;错误之处&#xff0c;还请指正&#xff0c;谢谢 :) 1. Architecture 2. General Purpose & System Register 名词列表&#…

Spring Cloud Alibaba 网关 Gateway 集成(7)

项目的源码地址 Spring Cloud Alibaba 工程搭建&#xff08;1&#xff09; Spring Cloud Alibaba 工程搭建连接数据库&#xff08;2&#xff09; Spring Cloud Alibaba 集成 nacos 以及整合 Ribbon 与 Feign 实现负载调用&#xff08;3&#xff09; Spring Cloud Alibaba Ribbo…

用标准的GNU/Linux命令替换Alpine上的精简版命令

Alpine Linux 是一个基于 musl libc 和 busybox 的轻量级Linux发行版&#xff0c;busybox 实现了很多常用类Unix命令的精简版&#xff0c;特点是体积很小&#xff0c;舍弃了很多不常用参数&#xff0c;我们简单对比一下标准Linux自带的 date 命令 和 Alpine下默认的 date 命令便…

Babel基础知识及实现埋点插件

目录 前言 AST 遍历 Visitors Paths&#xff08;路径&#xff09; Paths in Visitors&#xff08;存在于访问者中的路径&#xff09; State&#xff08;状态&#xff09; Scopes&#xff08;作用域&#xff09; Bindings&#xff08;绑定&#xff09; API babylo…

LeetCode 112. 路径总和 || LeetCode 113. 路径总和ii

LeetCode 112. 路径总和 1、题目 题目链接&#xff1a;112. 路径总和 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true…

唤醒手腕 Go 语言 并发编程、Channel通道、Context 详细教程(更新中)

并发编程概述 ​ 一个进程可以包含多个线程&#xff0c;这些线程运行的一定是同一个程序&#xff08;进程程序&#xff09;&#xff0c;且都由当前进程中已经存在的线程通过系统调用的方式创建出来。进程是资源分配的基本单位&#xff0c;线程是调度运行的基本单位&#xff0c…

CentOS 7安装配置docker

CentOS 7、8安装、配置docker 这里宿主机的型号选择是centos7.9.2009的版本 1.宿主机关闭防火墙和selinux&#xff0c;配置ipv4 #设置SELinuxdisabled vim /etc/selinux/config SELinuxdisabled 查看防火墙状态&#xff1a;firewall-cmd --state 关闭防火墙&#xff1a;syst…

C# WinForm —— 14 CheckedListBox 复选列表框介绍

1. 简介 类似 ListBox&#xff0c;提供项的列表&#xff0c;区别就是 CheckedListBox 每一个项前面有个复选框 2. 常用属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般以 ckl 开头BackColor背景颜色BoderStyle边框样式&#xff1a;无、FixedSingle、F…

探索静态住宅代理IP:网络安全的隐形守护者

在当今这个数字化高速发展的时代&#xff0c;网络安全问题愈发凸显其重要性。无论是企业级的网络运营&#xff0c;还是个人用户的网络活动&#xff0c;都需要一个安全、稳定的网络环境。而在这个环境中&#xff0c;静态住宅代理IP以其独特的优势&#xff0c;逐渐成为了网络安全…

如何通过PHP语言实现远程控制空调

如何通过PHP语言实现远程控制空调呢&#xff1f; 本文描述了使用PHP语言调用HTTP接口&#xff0c;实现控制空调&#xff0c;通过不同规格的通断器&#xff0c;来控制不同功率的空调的电源。 可选用产品&#xff1a;可根据实际场景需求&#xff0c;选择对应的规格 序号设备名称…

Go实现树莓派I2C读取SHT30温度湿度传感器

简介 树莓派其实本身包含很多资源引脚&#xff0c; 合理利用其实可以自制智能家居的一部分&#xff0c;本身硬件和Linux系统等高级语言支持加生态&#xff0c; 不说了&#xff0c; 做就好了… I2C 功能开启 参考之前的文章就可以了 Go实现树莓派读取bh1750光照强度 查看I2C总…

linux性能监控之top

说完了atop和htop&#xff0c;我们在来说说Linux自带的top&#xff0c;我们先看看命令效果&#xff1a; 可以看到是一个实时的系统监控工具&#xff0c;提供了一个动态的、交互式的实时视图&#xff0c;显示系统的整体性能信息以及正在运行的进程的相关信息。 我们先来解析下命…

重学java 35.API 6.包装类

心有所念&#xff0c;必有所灵 —— 24.5.10 一、基本数据类型对应的引用数据类型(包装类) 1概述 就是基本类型所对应的类&#xff08;包装类&#xff09;&#xff0c;我们需要将基本类型转为包装类&#xff0c;从而让基本类型拥有类的特性&#xff08;是基本类型可以使用包装类…

聊聊ChatGPT:智能语言模型背后的原理

目录 1. ChatGPT的基础&#xff1a;GPT模型 2. 预训练与微调&#xff1a;让模型更加智能 2.1 预训练 2.2 微调 3. 多样化的应用场景 4. 未来的展望 5. 结语 在当今的人工智能领域&#xff0c;OpenAI的ChatGPT无疑是一个炙手可热的话题。它不仅能流畅地进行对话&#xff…