【集合详解】TreeSet源码解析及自定义排序

上篇博客中,我们已经了解到TreeSet为有序集合,按照Comparator接口定义的排序顺序进行排序。一些基础类型,都已经实现了该接口,默认是按照自然排序进行排列。而我们自定义类型需要手动实现接口。

测试

首先我们来做一个测试。测试TreeSet的排序功能。

用例一:

在集合中添加了四个元素
这里写图片描述
输出结果是:ABCD

用例二:

颠倒顺序
这里写图片描述

输出结果是:ABCD
所以TreeSet的默认顺序并不是按照装入集合的先后排序的。而是按照字符的顺序。

用例三:

添加实体类

这里写图片描述
输出报错。我们跟踪源代码发现,当set进行添加时,Set.add(s2),会调用TreeMap方法

    public TreeMap(Map<? extends K, ? extends V> m) {
        comparator = null;
        putAll(m);
    }

其中putAll中调用compare方法,compare方法如下:

    final int compare(Object k1, Object k2) {
        return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
            : comparator.compare((K)k1, (K)k2);
    }

其中,compareTo在不明确排序类型标准时,无法进行比较。因此会报错:Student cannot be cast to java.lang.Comparable
通过以上看出,①如果想要对TreeSet实现指定的排序,需要自定义排序顺序。或是②如果TreeSet操作自定义类,也需要自定义排序顺序。

具体实现:

目标,TreeSet中存放学生实体,并能通过年龄进行排序。
上面博客中,我们提到了TreeSet的类构造函数,如果自定义排序,则一定需要

  public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }

需要传递Comparator接口这样一个实例,所以需要自己去定义Comparator的一个实现类。 然后实现该接口中compare 方法。
如下:
学生类:

扫描二维码关注公众号,回复: 2825520 查看本文章
public class Student {
    int age;
    public  Student(int age){
        this.age=age;
    }
public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

Comparator实现类:

 class StudentComparator implements Comparator{
    @Override
    public int compare(Object o1, Object o2) {
         Student s1=(Student)o1;
         Student s2=(Student)o2;
         //按照升序排列
        return s1.age-s2.age;
    }
}

调用:

TreeSet set=new TreeSet(new StudentComparator());

具体过程:

public static void main(String[] args){

     TreeSet set=new TreeSet(new StudentComparator());
Student s1=new Student(13);
     Student s2=new Student(10);
     Student s3=new Student(11);
     Student s4=new Student(12);

     set.add(s1);
     set.add(s2);
     set.add(s3);
     set.add(s4); 

     for (Iterator iterator = set.iterator(); iterator.hasNext();) {
        Student object = (Student) iterator.next();
        System.out.print(object.getAge()+" 、"); 
    }

结果按照年龄进行了排序:

这里写图片描述

PS:实际上这里通过Comparator也是应用了策略模式~

总结:

TreeSet自定义排序需要实现Comparator接口,并将该类型示例传入TreeSet初始化的参数中。在Comparator实现中写排序的方式和规则。,

猜你喜欢

转载自blog.csdn.net/u010176014/article/details/52096593
今日推荐