集合框架——TreeSet集合

泛型

泛型就是一种不确定的数据类型,使用<字母>,可以使用在类上,方法上和接口上。

泛型类

泛型类,指的是在类上有一个确定的数据类型,在创建该类对象时确定其数据类型。

//<E>: 表示一种不确定的数据类型
public class Box<E> {
    //定义一个变量
    private E element;

    public E getElement() {
        return element;
    }

    public void setElement(E element) {
        this.element = element;
    }
}
//泛型类上的<E>,在创建对象的时候确定数据类型
public class Demo1 {
    public static void main(String[] args) {
        //确定Box类中<E>的数据类型为String
        Box<String> box1=new Box<>();
        box1.setElement("hello");
        String element = box1.getElement();
        System.out.println(element);
		
        ///确定Box类中<E>的数据类型为Integer
        Box<Integer> box2=new Box<>();
        box2.setElement(100);
        Integer element2 = box2.getElement();
        System.out.println(element2);
    }
}

泛型方法

泛型方法,表示在方法上有一个不确定的数据类型,在调用这个方法时来确定其数据类型

public class Demo3{
    public static void main(String[] args){
        Collection<String> coll1 = addElement(new LinkedList<String>(), "abc", "bbc");
        Collection<Integer> coll2 = addElement(new ArrayList<Integer>(), 10, 20,30);

        System.out.println(coll1);
        System.out.println(coll2); 
    }

    //给一个集合添加元素
    //可变参数: 数据类型...变量名
    //T...arr 表示可以接收多个T类型的数据,等价于T[] arr
    public static <T> Collection<T>  addElement(Collection<T> list, T...arr){
        for (int i = 0; i < arr.length; i++) {
            list.add(arr[i]);
        }
        return list;
    } 
}

泛型接口

泛型接口指的是,在接口上有一个不确定的数据类型,可以在接口的实现类上确定其数据类型;‘

也可以把接口的泛型沿用到实现类上,在创建类的对象时确定其数据类型。

//Inter<T>: 在Inter接口上不确定的数据类型T
public interface Inter<T>{
    public void method(T t);
}
  • 情况1:在实现类上确定Inter的泛型
//Inter<String>: 确定接口上的泛型为String
public class InterImpl implements Inter<String>{
    public void method(String t){
        ....
    }
}
  • 情况2:把接口的泛型,沿用到实现类上
//把Inter接口上的泛型<T>,沿用到InterImpl2类上
public class InterImpl2<T> implements Inter<T>{
    public void method(T t){
        ....
    }
}
  • 测试类
public class Demo4{
    public static void main(String[] args){
        InterImpl impl1=new InterImpl();
        impl1.method("hello");
        
        InterImpl2<Integer>  impl2=new InterImpl2<Integer>();
        impl2.method(20);
        
        InterImpl2<String>  impl3=new InterImpl2<String>();
        impl3.method("world");
    }
}

泛型通配符

<?> : 可以是任意类型
<? extends Number>: Number或者Number的子类
<? super Number>: Number或者Number的父类

注意:一般泛型通配符是使用在方法的参数上,限定参数的数据类型。

Set集合

TreeSet集合可以对元素进行排序,排序有两个方式,分别是自然排序和比较器排序

自然排序

  • 自定义的类,实现Comparable接口,复写compareTo方法
public class Student implements Comparable<Student>{
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name; 
        this.age = age;
    }

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

    @Override
    public int compareTo(Student o) {
        //告诉TreeSet,排序规则:按照学生的年龄升序排列
        int num = this.age - o.age; 

        //如果年龄相同,就按照姓名比较
        if (num == 0) {
            num = this.name.compareTo(o.name);
        } 

        return num;
    }
}
  • 创建TreeSet集合,存储Student元素,每次存储元素的时候,会自动对元素进行排序
public class SetDemo2 {
    public static void main(String[] args) {
        Set<Student> set = new TreeSet<>();

        set.add(new Student("aaa", 18));
        set.add(new Student("ccc", 17));
        set.add(new Student("bbb", 19));
        set.add(new Student("eee", 20));
        set.add(new Student("ddd", 20));

        for (Student student : set) {
            System.out.println(student);
        }
    }
}

比较器排序

在创建TreeSet集合的时候,指定Comparator比较器,对集合中的元素进行排序

//在创建TreeSet对象时,指定比较器Comparator
Set<Student> set = new TreeSet<>(new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getAge()-o2.getAge(); //升序:从小到大
    }
});

set.add(new Student("aaa", 18));
set.add(new Student("ccc", 17));
set.add(new Student("bbb", 19));
set.add(new Student("eee", 20));
set.add(new Student("ddd", 20));

for (Student student : set) {
    System.out.println(student); 
}

两种排序方式如何选择

1. 如果使用API中已有的类作为TreeSet元素,
	当API中的类已经实现了Comparable自然排序的规则,但是这个排序规则不满足我们的要求
    这个时候,我们可以选择Comparator比较器排序。
   
2. 如果是自定义的类作为TreeSet元素,比较器排序或者自然排序,任选一个就可以了。

二叉树结构(了解)

TreeSet集合可以对元素进行排序,是因为底层的数据结构是二叉树。

二叉树:由若干个节点组成的树形结构,一个节点最多有两个子节点

二叉查找树(二叉搜索树,二叉排序树):对于任意一个节点,左边存储较小的节点,右边存储较大的节点

二叉平衡树:对于任意一个节点,左子树和右子树的高度差不超过1
	左旋:如果右子树比左子树的高度差超过1,就需要进行左旋,以达到再次平衡
	右旋:如果左子树比右子树的高差度超过1,就需要进行右旋,以达到再次平衡
	
导致二叉树不平衡的几种情况,如何恢复平衡?
	1.左左: 在根节点的左子树的左子树上添加节点,直接右旋
	2.左右: 在根节点的左子树的右子树上添加节点,先左旋,再右旋
	
	3.右右: 在根节点的右子树的右子树上添加节点,直接左旋
	4.右左: 在根节点的右子树的左子树上添加节点,先右旋,再左旋
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值