TreeSet/TreeMap的排序规则与涉及泛型约数的解释

首先TreeSet底层构造器实际是TreeMap(有key.value为null);

TreeMap的底层是红黑树(二叉树);

这里并没有分析底层,只是说明我的一些问题。

一.前置技能

  1.   排序分为自然排序和定制排序。自然排序(按元素值大小)需该对象所属类实现comparable<T>接口,定制排序自定义比较器实现comparator<T>接口。
  2. TreeSet/TreeMap的排序需要排序对象依赖comparable<T>接口和comparator<T>接口,基本数据包装类已经实现了这些接口,可以直接进行排序(自然排序)。而自定义对象需实现这些接口(无论是自然排序还是定制排序)。
  3. 自定义类实现comparable<T>接口 需重写 public int compareTo(T t){}方法;
           public int compareTo(Person o) {
    		// TODO Auto-generated method stub
    		System.out.println(this+"父类比较方法"+o);
    		int tmp=this.age-o.age;
    		return tmp==0?this.name.compareTo(o.name):tmp;
    	}

     

  4. 实现comparator<T>接口需要新建比较器实现该接口并重写public int compare(T t1, T t2) {}方法。然后调用TreeSet的构造器:TreeSet(Comparator<?  super E>c)来完成定制排序.
    public class ComparatoByName implements Comparator<Person> {
      /*
       * 定制排序比较器
       * 可以接受父类及其子类
       */
    	public int compare(Person o1, Person o2) {
    		// TODO Auto-generated method stub
    		int  tmp=o1.getName().compareTo(o2.getName());
    		return tmp==0?o1.getAge()-o2.getAge():tmp;
    	}
    }
    
    TreeSet<Person> ts=new TreeSet<Person>(new ComparatoByName());
    //子类也可以   原因是TreeSet(Comparator<?  super E>c)
    TreeSet<Student> ts=new TreeSet<Student>(new ComparatoByName());

     

二.拓展。

    1.对于自然排序实现comparatable<T>接口的类来说,他的子类为泛型的集合依然可以借用父类的comparaTo方法实现自然排序。因为父类实现接口重写方法后 子类可以继承到这个方法。当然也可以自己重写该方法,新的排序规则。

Q:Java_TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常?

P:所以在TreeSet/TreeMap中,添加对象为父类就调用父类的compareTo方法,子类调用子类的compareTo方法

    2.对于定制排序的比较器类实现的comparator<T> 也可以接受子类类型的集合来调用该比较器实现排序,是因为

因为比较器的实现的接口为Comparator<? super E> 这里的对象? 可以是E或E的父类:比如上面的代码中比较器实现的接口为Person类为父类(就是“?”)而TreeSet确实Student类子类依然可以排序成功。

   3.对于工具类Collections也内置了一个静态方法Collections.sort();他的参数类型是

  public static <T extends Comparable<? super T>> void sort(List<T> list) {
        Collections.sort(list);
    }

这里的泛型解释:这里的T类型必须实现Comparable<>接口并且可以是这个Comparable<>泛型约束的子类,使该方法在针对自定义类型时更加灵活。更多解释在https://www.cnblogs.com/xiaomiganfan/p/5390252.html。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值