【进阶篇-Day10:JAVA中泛型、平衡二叉树、红黑树、TreeSet集合的介绍】

news2024/9/23 1:24:47

目录

  • 1、泛型
    • 1.1 泛型类
    • 1.2 泛型方法
    • 1.3 泛型接口
    • 1.4 泛型通配符
    • 1.5 总结
  • 2、数据结构(树)
    • 2.1 树的基本介绍
    • 2.2 二叉树的介绍
      • 2.2.1 概念:
      • 2.2.2 二叉查找树的介绍:
      • 2.2.3 二叉查找树添加节点:
      • 2.2.4 二叉查找树查找节点:
      • 2.2.5 二叉查找树的弊端:
      • 2.2.6 平衡二叉树:
        • (1)左旋转:
        • (2)右旋转:
        • (3)平衡二叉树需要旋转的四种情况:
    • 2.3 红黑树
      • 2.3.1 概念:
      • 2.3.2 规则:
      • 2.3.3 红黑树添加节点:
  • 3、TreeSet集合
    • 3.1 自然排序
    • 3.2 比较器排序
    • 3.3 两种比较器如何选择

1、泛型

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

下面是泛型的举例:

package com.itheima.generics;

import java.util.ArrayList;

public class GenericsDemo1 {
    /**
     * 泛型介绍:JDK5引入的,可以在编译阶段约束操作的数据类型,并进行检查
     *
     * 注意:泛型默认的数据类型时Object
     *
     * 泛型的好处:
     *          1、统一数据类型
     *          2、将运行期的错误提升到编译器
     *
     *  泛型需要掌握:
     *          1、泛型类
     *          2、泛型方法
     *          3、泛型接口
     *          4、泛型通配符
     *          5、泛型的限定
     */
    public static void main(String[] args) {
        //ArrayList如果定义类型为String,则就规定此list装的是String类型的对象(统一数据类型)
        ArrayList<String> list = new ArrayList<>();
        list.add("zhangsan");
        list.add("lisi");
        list.add("wangwu");
//        list.add(111);//编译就会报错(将运行期的错误提升到编译器)
    }
}

了解了什么是泛型之后,接下来看下:上述介绍的泛型类、泛型方法 、泛型接口、泛型通配符,以及泛型的限定等。
在这里插入图片描述

1.1 泛型类

在这里插入图片描述

package com.itheima.generics;

public class GenericsDemo2 {
    /**
     *  泛型类演示:
     *
     *  常见的泛型标识符: E V K T
     *          E:Element
     *          T:Type
     *          K:Key(键)
     *          V:Value(值)
     *
     *   清楚不同的泛型,在什么时机能确定到具体的类型
     *   泛型类在创建对象的时候就会确定具体的类型
     */
    public static void main(String[] args) {
        //指定为String类型
        Student<String> s = new Student<>();
        //指定为Integer类型
        Student<Integer> s2 = new Student<>();
    }
}

class Student<E>{
    /**
     * 泛型类的好处是:里面的方法和属性在定义类时不指定,在创建对象时再指定即可
     */
    private E name;
}

1.2 泛型方法

在这里插入图片描述

package com.itheima.generics;

public class GenericsDemo3 {
    /**
     * 泛型方法:
     * 1、非静态的方法:内部的泛型,会根据类的泛型去匹配
     *        - 时机:在创建对象时,确定到具体的类型
     * 2、静态的方法:静态方法中如果加入泛型,必须声明出自己独立的泛型
     *        -时机:在调用方法,传入实际参数的时候,确定到具体的类型
     */
    public static void main(String[] args) {
        String[] arr1 = {"1", "2", "3"};
        Integer[] arr2 = {1, 2, 3};
        Double[] arr3 = {1.0, 2.0, 3.0};
        printArray(arr1);
        printArray(arr2);
        printArray(arr3);
    }

    /**
     * 2、静态的方法:静态方法中如果加入泛型,必须声明出自己独立的泛型
     *            -时机:在调用方法,传入实际参数的时候,确定到具体的类型
     */
    public static <T> void printArray(T[] arr) {
        System.out.println("[");
        for (int i = 0; i < arr.length - 1; i++) {
            System.out.println(arr[i] + ",");
        }
        System.out.println(arr[arr.length - 1] + "]");
    }
}

class Teacher<E> {
    private E name;
    

    /**
     * 1、非静态的方法:内部的泛型,会根据类的泛型去匹配
     *         - 时机:在创建对象时,确定到具体的类型
     * @param e
     */
    public void show(E e) {
    }
}

1.3 泛型接口

在这里插入图片描述

package com.itheima.generics;

public class GenericsDemo4 {
    /**
     * 泛型接口:
     *         1、实现类,实现接口的时候,确定到具体的类型
     *         2、实现类实现接口,没有指定具体类型,就让接口的泛型,跟着类的泛型去匹配
     */
    public static void main(String[] args) {

    }
}

interface Inter<T>{
    void show(T t);
}

/**
 * 1、实现类,实现接口的时候,确定到具体的类型
 */
class InterAImpl implements Inter<String>{

    @Override
    public void show(String s) {

    }
}

/**
 * 2、实现类实现接口,没有指定具体类型,就让接口的泛型,跟着类的泛型去匹配
 */
class InterBImpl<T> implements Inter<T>{

    @Override
    public void show(T t) {

    }
}

1.4 泛型通配符

在这里插入图片描述

package com.itheima.generics;

import java.util.ArrayList;
import java.util.Objects;

public class GenericsDemo5 {
    /**
     * 泛型通配符:
     *          ?:任意类型
     *          ? extends E:可以传入的是E,或者是E的子类
     *          ? super E:可以传入的是E,或者是E的父类
     */
    public static void main(String[] args) {
        //第一个ArrayList定义为 Coder 类型
        ArrayList<Coder> list1 = new ArrayList<>();
        list1.add(new Coder());

        //第二个ArrayList定义为 Manager 类型
        ArrayList<Manager> list2 = new ArrayList<>();
        list2.add(new Manager());

        //调用同一个方法时,可以使用泛型通配符
        method(list1);
        method(list2);
    }

    /**
     * 使用泛型通配符?来表示任意类型
     *
     */
    public static void method(ArrayList<? extends Employee> list){
        for(Object b : list){
            //强转为抽象类类型
            Employee e = (Employee)b;
            e.work();
        }
    }
}

abstract class Employee{
    abstract void work();
}

class Coder extends Employee{
    @Override
    void work() {
        System.out.println("我是程序员!!!");
    }
}

class Manager extends Employee{
    @Override
    void work() {
        System.out.println("我是项目经理!!!");
    }
}

1.5 总结

在这里插入图片描述

2、数据结构(树)

2.1 树的基本介绍

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 二叉树的介绍

2.2.1 概念:

在这里插入图片描述

2.2.2 二叉查找树的介绍:

在这里插入图片描述

2.2.3 二叉查找树添加节点:

在这里插入图片描述

2.2.4 二叉查找树查找节点:

在这里插入图片描述

2.2.5 二叉查找树的弊端:

在这里插入图片描述

在这里插入图片描述

2.2.6 平衡二叉树:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

(1)左旋转:
  • 案例一:
    在这里插入图片描述

在这里插入图片描述

  • 案例二:
    在这里插入图片描述
    在这里插入图片描述
(2)右旋转:
  • 案例一:
    在这里插入图片描述

在这里插入图片描述

  • 案例二:
    在这里插入图片描述
    在这里插入图片描述
(3)平衡二叉树需要旋转的四种情况:

在这里插入图片描述

  • 左左:
    在这里插入图片描述
    在这里插入图片描述

  • 左右:
    在这里插入图片描述
    先把左子树左旋:
    在这里插入图片描述
    再整体右旋:
    在这里插入图片描述

  • 右右:
    在这里插入图片描述
    在这里插入图片描述

  • 右左:
    在这里插入图片描述
    先对右子树做一次右旋转,如下:
    在这里插入图片描述
    再整体做一次左旋转:
    在这里插入图片描述

2.3 红黑树

2.3.1 概念:

在这里插入图片描述

在这里插入图片描述

2.3.2 规则:

在这里插入图片描述

2.3.3 红黑树添加节点:

在这里插入图片描述

在这里插入图片描述

3、TreeSet集合

在这里插入图片描述

TreeSet集合的特点:去重、排序

TreeSet的两种排序
在这里插入图片描述

3.1 自然排序

在这里插入图片描述

package com.itheima.set;
import java.util.TreeSet;

public class TreeSetDemo1 {
    /**
     * TreeSet集合的特点:排序、去重
     *
     */
    public static void main(String[] args) {
        //1、存字符串类型
        TreeSet<String> ts1 = new TreeSet<>();
        ts1.add("b");
        ts1.add("c");
        ts1.add("a");
        ts1.add("a");
        ts1.add("x");
        ts1.add("b");
        //排序并去重
        System.out.println(ts1);//[a, b, c, x]

        /**
         * 2、存自定义类型:需要 Student 继承 Comparable并实现他的 compareTo 方法
         *      compareTo方法返回值:
         *               0:相等,因此只有第一条数
         *               1:正序排列
         *              -1:倒叙排列
         */

        TreeSet<Student> ts2 = new TreeSet<>();
        ts2.add(new Student("张三", 12));
        ts2.add(new Student("李四", 23));
        ts2.add(new Student("王五", 23));
        ts2.add(new Student("赵六", 11));
        System.out.println(ts2);//[Student{name='赵六', age=11}, Student{name='张三', age=12}, Student{name='李四', age=23}, Student{name='王五', age=23}]
    }
}


public class Student implements Comparable<Student>{
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public int compareTo(Student o) {
        /**
         * this.xxx - o.xxx  正序
         * o.xxx - this.xxx  降序
         */
        //根据年龄做主要排序
        int ageResult = this.age - o.age;
        //要是年龄相等,则使用姓名做次要排序
        int result = ageResult == 0 ? this.name.compareTo(o.name) : ageResult;
        return result;
    }

    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;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

3.2 比较器排序

在这里插入图片描述

package com.itheima.set;

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetDemo2 {
    /**
     * 如果同时具备比较器和自然排序,会优先按照比较器的规则,进行排序操作
     * @param args
     */
    public static void main(String[] args) {
        //使用匿名内部类重写compare方法,即比较器,自定义比较规则
        TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int ageResult = o2.getAge() - o1.getAge();
                int nameResult = ageResult ==0 ? o1.getName().compareTo(o2.getName()) : ageResult;
                return nameResult;
            }
        });
        ts.add(new Student("张三", 12));
        ts.add(new Student("李四", 23));
        ts.add(new Student("王五", 23));
        ts.add(new Student("赵六", 11));

        System.out.println(ts);//[Student{name='李四', age=23}, Student{name='王五', age=23}, Student{name='张三', age=12}, Student{name='赵六', age=11}]
    }
}

3.3 两种比较器如何选择

在这里插入图片描述

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

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

相关文章

window11 部署llama.cpp并运行Qwen2-0.5B-Instruct-GGUF

吾名爱妃&#xff0c;性好静亦好动。好编程&#xff0c;常沉浸于代码之世界&#xff0c;思维纵横&#xff0c;力求逻辑之严密&#xff0c;算法之精妙。亦爱篮球&#xff0c;驰骋球场&#xff0c;尽享挥洒汗水之乐。且喜跑步&#xff0c;尤钟马拉松&#xff0c;长途奔袭&#xf…

从零开始读RocketMq源码(五)Consumer消费Message流程解析

目录 前言 准备 拉取服务和重平衡服务启动 初识PullRequest 重平衡服务 对重平衡资源进行排序 MessageQueue消息队列集合来源 Consumer消费者集合数据来源 确实分配资源策略 执行分配策略 初始化ProcessQueue 初始化PullRequest 内存队列填充PullRequest 消息拉取…

hackmyvm--Decode

环境 靶机&#xff1a;ip未知 攻击机kali&#xff1a;192.168.233.128 192.168.56.101 主机探测 锁定靶机ip为108 端口扫描 nmap -p- -T4 -A 192.168.56.108 常规套路80和22 web打点 dirsearch -u http://192.168.56.108/ 访问robots,txt文件 访问/decode 发现其自动添加了/,怀…

Chromium源码阅读(9):了解Log模块

Chromium许多日志被TraceEvent代替了&#xff0c;因此TraceEvent出现的频率要比Log高很多。 但是也有不少场景使用Log。 在blink&#xff0c;Log的实现由base提供&#xff0c;而blink/render/core/base/logging.h进行了二次封装。 日志系统的设计细节 错误对话框处理 错误消…

Qt第十二章 样式表

样式表 文章目录 样式表1.样式表盒子模型 2.选择器选择器类型伪状态选择器Pseudo-State 3.控件示例4继承自QWidget的类&#xff0c;设置qss样式表没有效果&#xff0c;需要重写paintEvent 1.样式表 盒子模型 2.选择器 样式表语法&#xff0c;选择器{属性1:值;属性2:值;}如果只…

韦东山嵌入式linux系列-驱动进化之路:设备树的引入及简明教程

1 设备树的引入与作用 以 LED 驱动为例&#xff0c;如果你要更换LED所用的GPIO引脚&#xff0c;需要修改驱动程序源码、重新编译驱动、重新加载驱动。 在内核中&#xff0c;使用同一个芯片的板子&#xff0c;它们所用的外设资源不一样&#xff0c;比如A板用 GPIO A&#xff0c…

鸿蒙仓颉语言【类型class】

类与结构&#xff08;class & struct&#xff09; 面向对象的编程语言&#xff0c;必不可少的基础元素&#xff0c;类或者叫类型&#xff0c;在仓颉中类可以抽象(abstract)、继承&#xff08;<:&#xff09;&#xff0c;公开&#xff08;Public&#xff09;或者私有&am…

在jsPsych中使用Vue

jspsych 介绍 jsPsych是一个非常好用的心理学实验插件&#xff0c;可以用来构建心理学实验。具体的就不多介绍了&#xff0c;大家可以去看官网&#xff1a;https://www.jspsych.org/latest/ 但是大家在使用时就会发现&#xff0c;这个插件只能使用js绘制界面&#xff0c;或者…

【算法专题】归并排序

目录 1. 排序数组 2. 交易逆序对的总数 3. 计算右侧小于当前元素的个数 4. 翻转对 总结 1. 排序数组 912. 排序数组 - 力扣&#xff08;LeetCode&#xff09; 今天我们使用归并排序来对数组进行排序&#xff0c;实际上&#xff0c;归并排序和快速排序是有一定相似之处的&a…

什么是蓝牙芯片?蓝牙芯片和蓝牙模块的区别

蓝牙芯片&#xff0c;是一种集成了蓝牙无线通信技术的微型电子元件。它如同一个微小的通信枢纽&#xff0c;能够在各种电子设备之间建立无线连接&#xff0c;实现数据的传输与共享。蓝牙芯片的设计精妙而复杂&#xff0c;内部集成了射频前端、数字基带、协议栈等多个功能模块&a…

Linux中nohup(no hang up)不挂起,用于在系统后台不挂断地运行命令,即使退出终端也不会影响程序的运行。

nohup的英文全称是 no hang up&#xff0c;即“不挂起”。这个命令在Linux或Unix系统中非常有用&#xff0c;主要用于在系统后台不挂断地运行命令&#xff0c;即使退出终端也不会影响程序的运行。默认情况下&#xff08;非重定向时&#xff09;&#xff0c;nohup会将输出写入一…

linux中常见的协议、服务端口整理汇总

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 ​ &#x1f3c5;阿里云ACE认证高级工程师 ​ &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社…

排序系列 之 插入排序

&#xff01;&#xff01;&#xff01;排序仅针对于数组哦本次排序是按照升序来的哦 介绍 插入排序英文名为InsertSort 基本思路 1、认为数组当中的第一个数值已经排好序了2、定义一个游标从第二个数值开始不断地向后进行遍历3、游标指向的数据插入已经排好序的数组中 代码…

力扣刷题之2959.关闭分部的可行集合数目

题干描述 一个公司在全国有 n 个分部&#xff0c;它们之间有的有道路连接。一开始&#xff0c;所有分部通过这些道路两两之间互相可以到达。 公司意识到在分部之间旅行花费了太多时间&#xff0c;所以它们决定关闭一些分部&#xff08;也可能不关闭任何分部&#xff09;&…

AV1 编码标准屏幕内容编码技术概述

AV1 屏幕内容编码 为了提高屏幕捕获内容的压缩性能&#xff0c;AV1采用了几种编码工具&#xff0c;例如用于处理屏幕画面中重复模式的内帧内块复制&#xff08;IntraBC&#xff09;&#xff0c;以及用于处理颜色数量有限的屏幕块的调色板模式。 帧内块拷贝 AV1 编码中的 Intra …

【Vue】快速入门:构建你的第一个Vue 3应用

文章目录 一、Vue简介二、环境搭建1. 安装Node.js和npm2. 安装Vue CLI 三、创建Vue项目四、项目结构介绍五、组件基础创建一个组件使用组件 六、模板语法插值指令v-bindv-ifv-for 七、事件处理八、状态管理安装Vuex创建Store使用Store 九、路由基础安装Vue Router配置路由使用路…

FFmpeg播放视频

VS2017+FFmpeg6.2.r113110+SDL2.30.5 1.下载 ShiftMediaProject/FFmpeg 2.下载SDL2 3.新建VC++控制台应用 3.配置include和lib 4.把FFmpeg和SDL的dll 复制到工程Debug目录下,并设置调试命令

24年Hvv准备,6大方向,33篇技战法

进去不少小伙伴后台留言说需要技战法&#xff0c;因此小编对市面上的技战法进行了收集和总结&#xff0c;并对收集来的技战法进行了分类&#xff0c;总共分了6大类&#xff0c;共计33篇&#xff1a; 有需要的小伙伴关注我&#xff0c;点击在看&#xff0c;并私信回复“技战法”…

IO、进程、线程03

第一题&#xff1a;预习 opendir 和 readdir函数 opendir 和 readdir 是两个在C语言&#xff08;特别是使用POSIX标准的系统&#xff0c;如Linux和UNIX&#xff09;中用于目录遍历的函数。这两个函数属于标准的C库中的目录操作部分&#xff0c;通常与<dirent.h>头文件一…

MySQL学习记录 —— 이십일 MySQL服务器文件系统(1)

文章目录 1、配置和默认值2、系统变量和选项1、介绍2、常用选项3、如何使用系统变量 3、常用服务器配置4、查看状态变量5、MySQL数据目录 mysql的服务端就是mysqld&#xff0c;d就是daemon&#xff0c;守护进程的意思。 配置文件中[mysqld]部分时服务器支持的启动选项。服务器…