Java进阶07集合(续)

news2024/12/23 10:30:15

Java进阶07 集合(续)

一、数据结构(树)

1、关于树

1.1 相关概念
  • 节点:树中每个单独的分支

  • 节点的度:每个节点的子节点数量

  • 树高:树的总层数

  • 根节点:最顶层节点

  • 左子节点:左下方的节点

  • 右子节点:右下方的节点

  • 左子树:节点左下方连接的全部节点

  • 右子树:节点右下方连接的全部节点

1.2 二叉树&二叉查找树

  • 普通二叉树

    树中任意节点的度都<=2

  • 二叉查找树

    又称二叉排序树、二叉搜索树。其特点是:①首先必须是二叉树;②任意节点左子树上的值均小于当前节点值;③任意节点右子树上的值都大于当前节点值;

    二叉查找树的节点如果都挂在同一边,会产生瘸腿现象,那么它的查询效率就和普通的单链表一样了,为了解决这个问题,引入平衡二叉树

1.3 平衡二叉树

在是二叉查找树的前提下,任意节点的左右子树高度差不超过1,即为平衡二叉树。由于平衡二叉树的这个特点,每次往该树中加入新的节点时,就可能会对其平衡性有影响。当添加了某个节点后,改变了该树的平衡性,则会触发旋转机制来保证平衡性

  • 旋转规则

    确定支点:从添加的结点开始,不断往父节点找不平衡的节点,这个点就是支点

    • 左旋(右右加入造成不平衡)

      case1.支点没有左子节点

      把支点左旋降级,变成左子节点;晋升原来的右子节点

      case2.支点有左子节点

      将根节点的右侧往左拉;原先的右子节点变成新的父节点,并把多余的左子节点让出,给已经降级的根节点当右子节点

    • 右旋(左左加入造成不平衡)

      case1.支点没有右子节点

      把支点右旋降级,变成右子节点;晋升原来的左子节点

      case2.支点有右子节点

      将根节点的左侧往右拉;原先的左子节点变成新的父节点,并把多余的右子节点让出,给已经降级的根节点当左子节点

  • 需要旋转的四种情况

    左左意思为根节点的左子树的左子树加入导致的不平衡,其余三种情况类似

    • 左左:一次右旋

    • 左右:先局部左旋,再整体右旋

    • 右右:一次左旋

    • 右左:先局部右旋,再整体左旋

2、红黑树

2.1 红黑树的概念

红黑树是一种自平衡的二叉查找树,是一种特殊的二叉查找树,红黑树的每一个节点上都有存储位表示节点的颜色,节点颜色非黑即红。红黑树不是高度平衡的,它的平衡是通过”红黑规则“实现的。

2.2 红黑规则

①每一个节点是红色或黑色

根节点必须是黑色

③如果一个节点没有子节点或父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的

④如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个相邻的红节点

⑤对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点

助记口诀:左根右、根叶黑、不红红、黑路同
  • 左根右:左子树节点值<=根节点值<=右子树节点值

  • 根叶黑:根节点和叶节点(外部节点Nil)均是黑色的

  • 不红红:不能出现两个相邻的红节点

  • 黑路同:从某个节点出发,一条路走到黑(即走到它的后代叶节点上)经过的黑色节点数都相同

2.3 添加节点规则

3、动画演示网站

Data Structure Visualization (usfca.edu)

二、TreeSet集合

1、作用

对集合中的元素进行排序操作(底层红黑树实现);且属于Set派系,不允许存储重复数据,可以去重

1.1 综合案例

需求:键盘录入一个字符串,对字符串中的字符去重,并排序

public class TreeSetTest1 {
    public static void main(String[] args) {
        System.out.println("请输入:");
        String content = new Scanner(System.in).nextLine();
​
        //1、将字符串拆分为字符数组,方便获取每一个字符
        char[] chars = content.toCharArray();
        //2、准备TreeSet集合用于排序和去重
        TreeSet<Character> set = new TreeSet<>();
​
        //3、遍历字符数组,并将每一个字符添加到集合
        for (char c : chars) {
            set.add(c);
        }
​
        //4、多次拼接且不知道拼接次数,创建StringBuilder拼接
        StringBuilder sb = new StringBuilder();
        
        //注意:Set集合遍历方式只有三种(迭代器、增强for、foreach方法)
        set.forEach(c->sb.append(c));
​
        //展示拼接后的内容
        System.out.println(sb);
    }
}

2、排序方式

2.1 默认排序方式
  • Integer类,默认按数值大小排序

  • String类,默认按照其对应的编码表中的整数值逐个比较,均相同的会按照长度比较,短的在前

    TreeSet<String> set1 = new TreeSet<>();
     set1.add("aaa");
     set1.add("aaaa");
     set1.add("aab");
     set1.add("cde");
    ​
     System.out.println(set1);
    ​
    //排序结果为:aaa aaaa aab cde
2.2 自然排序
  • 类实现Comparable接口

  • 重写CompareTo方法

  • 根据方法的返回值,来组织排序规则(返回负数往左,返回正数往右,返回0不存)

    public class TreeSetDemo2 {
        public static void main(String[] args) {
            TreeSet<Student> set = new TreeSet<>();
    ​
            set.add(new Student("张三",23));
            set.add(new Student("李四",24));
            set.add(new Student("王五",25));
    ​
            System.out.println(set);
        }
    }
    ​
    //Student类要实现Comparable接口,重写compareTo方法的内部逻辑,此处年龄为主要排序依据,姓名为次要排序依据
    @Override  //年龄正序
    public int compareTo(Student o) {
        int ageResult = this.age-o.age;   //按年龄正序排列   倒序为o.age-this.age
        int nameResult = ageResult == 0 ? this.name.compareTo(o.name) : ageResult;
        //同名同年龄的需要保留,返回1或-1都无所谓,因为内容一样,谁前谁后不重要
        return nameResult == 0 ? 1 : nameResult;
    }
2.3 比较器排序(覆盖自然排序)
  • 在TreeSet的构造方法中,传入Compartor接口的实现类对象

  • 重写compare方法

  • 根据方法的返回值,来组织排序规则(返回负数往左,返回正数往右,返回0不存)

    public class TreeSetDemo3 {
        /*
           需求:对字符串进行排序,根据字符串的长度,从大到小排序
        */
        public static void main(String[] args) {
            //String类为Java写好的类,已具备自然排序,但不是我想要的排序规则,需要比较器排序
            TreeSet<String> set = new TreeSet<>(new Comparator<String>() {
                
                //重写compare方法
                @Override
                public int compare(String o1, String o2) {
                    //按长度倒序排列    o1.xxx-o2.xxx  正序  
                    int lengthResult = o2.length()-o1.length();
                    return lengthResult==0?o2.compareTo(o1):lengthResult;
                }
            });
    ​
            set.add("aaa");
            set.add("aa");
            set.add("bbbb");
            set.add("bb");
            set.add("aaaa");
    ​
            System.out.println(set);
        }
    }

3、排序如何选择

Java已经写好的类(如String、Integer、Double...)大多数都具有自然排序的规则(String默认按字典顺序、Integer默认升序、Double默认升序),这些规则放在源码中,我们无法修改其比较规则,如果我们要实现的排序规则跟自然排序不一样,此时需要使用比较器排序来覆盖自然排序规则。因为当同时具备自然排序和比较器排序时,会优先按照比较器进行排序操作;

4、利用TreeSet集合降序排列ArrayList

方法说明
static <T> void sort(T[] a,Comprtor<? super T> c)根据指定比较器产生的顺序指定对象数组进行排序
public class ArraysDemo {
    public static void main(String[] args){
        //利用集合TreeSet集合方法对数组降序排列
        Integer[] arr3 ={11,55,33,22,44};
        Arrays.sort(arr3, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;     //o2-o1降序
            }
        });
        System.out.println(Arrays.toString(arr3));
    }
}

三、HashSet集合

1、关于HashSet底层

集合底层采取哈希表存储数据,JDK8之前的哈希表是数组+链表;JDK8之后的哈希表是数组+链表+红黑树。哈希表是一种对于增删改查数据性能都比较好的结构

2、配合去重

HashSet特点就是去重。为了保证元素唯一,必须同时重写HashCode和equals方法!!!

2.1 配合去重流程

往集合中添加对象→→→调用对象的HashCode方法**,计算出一个应存入的索引地址→→→查看该位置上是否已存在元素→→→不存在则直接存;存在,调用equals方法比较内容→→→内容不同,存入集合;内容相同,不存入。

2.2 HashCode方法
  • 该方法底层调用了C++代码计算出一个随机数(常被人称为地址值)

  • 是JDK根据某种规则算出来的int类型的整数

  • 我们不必太过关注其内部实现,可以把它简单的理解为会计算出某个对象对应的整数值

  • 为了避免存入的时候元素都堆积在同一个索引位置,因此hashcode方法的重写就显得格外重要

    ⭐重写改造原则(降低索引冲突)⭐

    将对象的所有属性值都带入运算

    • 对象的属性相同,返回哈希值一定相同

    • 对象的属性不同,返回哈希值尽量不同

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

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

相关文章

融知财经:期货交易原理是怎样的?期货交易有哪些特征?

期货的原理是基于对某期货品种未来走势的判断而形成对其合约的买卖交易&#xff0c;因此期货可以解释为买涨或买跌。买涨&#xff0c;即看多交易&#xff0c;预期某期货品种未来价格上涨而进行的买入开仓交易&#xff1b;买跌&#xff0c;即看空交易&#xff0c;预期某期货品种…

招聘招商求职系统asp.net+sqlserver

招聘招商求职系统asp.netsqlserver 首 页 招聘信息 公寓信息 物品求购 发布信息 管理员后台登陆 账号密码TSoft 111 审核 招聘信息 求职信息 培训信息 说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a; 基于asp.net架构和sql s…

首席数据官CCRC-CDO如何构筑企业数据合规的坚固防线

在当今信息化快速发展的时代&#xff0c;数据已经成为企业最宝贵的资产之一。然而&#xff0c;随着数据规模的迅速增长&#xff0c;数据合规问题也日益凸显。首席数据官&#xff08;CDO&#xff09;作为企业中负责数据战略和管理的核心人物&#xff0c;构筑企业数据合规的坚固防…

【C++】map和set的基础详解

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

500 个 AI 项目代码库:计算机视觉到 NLP | 开源日报 No.248

ashishpatel26/500-AI-Machine-learning-Deep-learning-Computer-vision-NLP-Projects-with-code Stars: 16.8k License: NOASSERTION 500-AI-Machine-learning-Deep-learning-Computer-vision-NLP-Projects-with-code 是一个包含 500 多个 AI、机器学习、深度学习、计算机视觉…

变配电工程 变配电室智能监控系统 门禁 视频 环境 机器人

一、方案背景 要真正了解无人值守配电房的运行模式&#xff0c;我们必须对“无人值守”这一概念有准确的理解。它并不意味着完全没有工作人员管理&#xff0c;而是通过技术设备和人机协作来确保配电房的正常运行。 利用变配电室智能监控系统&#xff0c;可以实时获得配电室各…

【全开源】Java外卖微信小程序京东拼多多外卖cps|外卖红包优惠券源码美团饿了么红包

1.京东优惠小程序&#xff1a; 特色功能&#xff1a;京东优惠小程序提供丰富的商品优惠信息&#xff0c;包括京东独家的优惠券、折扣活动等。用户可以直接在小程序内浏览商品、领取优惠券、下单购买&#xff0c;无需跳转到京东APP或网页。优势&#xff1a;京东作为中国领先的电…

Android 按键消息流程源码分析

在Android系统中&#xff0c;键盘按键事件是由SystemServer服务来管理的&#xff1b;然后在以消息的形式分发给应用程序处理。产生键盘按键事件则是有Linux kernel的相关驱动来实现。键盘消息有别于其他类型的消息&#xff1b;需要从Linux kernel drivers产生由上层APP来处理。…

正点原子Linux学习笔记(六)在 LCD 上显示 jpeg 图像

在 LCD 上显示 jpeg 图像 20.1 JPEG 简介20.2 libjpeg 简介20.3 libjpeg 移植下载源码包编译源码安装目录下的文件夹介绍移植到开发板 20.4 libjpeg 使用说明错误处理创建解码对象设置数据源读取 jpeg 文件的头信息设置解码处理参数开始解码读取数据结束解码释放/销毁解码对象 …

[华为OD]C卷 BFS 亲子游戏 200

题目&#xff1a; 宝宝和妈妈参加亲子游戏&#xff0c;在一个二维矩阵&#xff08;N*N&#xff09;的格子地图上&#xff0c;宝宝和妈妈抽签决定各自 的位置&#xff0c;地图上每个格子有不同的Q糖果数量&#xff0c;部分格子有障碍物。 游戏规则Q是妈妈必须在最短的时间&a…

力扣刷题第1天:消失的数字

大家好啊&#xff0c;从今天开始将会和大家一起刷题&#xff0c;从今天开始小生也会开辟新的专栏。&#x1f61c;&#x1f61c;&#x1f61c; 目录 第一部分&#xff1a;题目描述 第二部分&#xff1a;题目分析 第三部分&#xff1a;解决方法 3.1 思路一&#xff1a;先排序…

WebView基础知识以及Androidx-WebKit的使用

文章目录 摘要WebView基础一、启动调整模式二、WebChromeClient三、WebViewClient四、WebSettings五、WebView和Native交互 Androidx-WebKit一、启动安全浏览服务二、设置代理三、安全的 WebView 和 Native 通信支持四、文件传递五、深色主题的支持六、JavaScript and WebAssem…

邮件大附件系统如何进行安全、高效的大附件发送?

邮件大附件系统是一套解决传统电子邮件系统&#xff0c;在发送大文件时遇到限制的解决方案。由于传统电子邮件系统通常对附件大小有限制&#xff0c;这使得发送大文件变得困难。邮件大附件系统通过各种技术手段&#xff0c;允许用户发送超过传统限制的大文件&#xff0c;通常在…

【随笔】Git 高级篇 -- 上传命令的参数 (下)git push(三十七)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

目标检测——低光可见光-红外配对数据集

引言 亲爱的读者们&#xff0c;您是否在寻找某个特定的数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 …

TypeScript学习日志-第二十四天(webpack构建ts+vue3)

webpack构建tsvue3 一、构建项目目录 如图&#xff1a; shim.d.ts 这个文件用于让ts识别.vue后缀的 后续会说 并且给 tsconfig.json 增加配置项 "include": ["src/**/*"] 二、基础构建 安装依赖 安装如下依赖&#xff1a; npm install webpack -D …

11.偏向锁原理及其实战

文章目录 偏向锁原理及其实战1.偏向锁原理2.偏向锁案例代码演示2.1.偏向锁案例代码2.2.1.无锁情况下状态2.1.2.偏向锁状态2.1.3.释放锁后的状态 2.2.偏向锁的膨胀和撤销2.2.1.偏向锁撤销的条件2.2.2.偏向锁的撤销 2.2.3.偏向锁的膨胀 2.3.全局安全点原理和偏向锁撤销性能问题2.…

在R的 RGui中,使用devtools 安装trajeR

创建于&#xff1a;2024.5.5 文章目录 1. 报错信息2. 尝试使用指定的清华镜像&#xff0c;没有解决3. 找到原因&#xff1a;官网把包删除了4. 尝试从网上下载&#xff0c;然后安装。没有成功5. 使用devtools安装5.1 尝试直接安装&#xff1a;install.packages("devtools&q…

OpenCV | 项目 | 虚拟绘画

OpenCV | 项目 | 虚拟绘画 捕捉摄像头 如果在虚拟机中运行&#xff0c;请确保虚拟机摄像头打开。 #include<opencv2/opencv.hpp>using namespace cv; using namespace std;int main() {VideoCapture cap(0);Mat img;while(1) {cap.read(img);imshow("Image"…

JetBrains的Java集成开发环境IntelliJ 2024.1版本在Windows/Linux系统的下载与安装配置

目录 前言一、IntelliJ在Windows安装二、IntelliJ在Linux安装三、Windows下使用配置四、Linux下使用配置总结 前言 ​ “ IntelliJ IDEA Ultimate是一款功能强大的Java集成开发环境&#xff08;IDE&#xff09;。它提供了丰富的功能和工具&#xff0c;可以帮助开发人员更高效地…