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

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 两种比较器如何选择

在这里插入图片描述

  • 23
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值