TreeSet集合经过了一系列操作,实现了Set接口
public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{
	……
	}
 
public interface NavigableSet<E> extends SortedSet<E> {
	……
	}
 
public interface SortedSet<E> extends Set<E> {
	……
	}
 
观察他的构造方法可以发现常用的有第一个和第三个
 也就是无参构造方法实现自然排序
 带参构造方法内采用匿名内部类实现了Comparator接口(比较器)
无参构造 | 自然排序
我们先说无参构造方法
 就以存储Student类对象为例子
package myCollection.set02;
/*这是Student类*/
public class Student {
    private String name;
    private int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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;
    }
}
 
package myCollection.set02;
import java.util.TreeSet;
public class TreeSetDemo {
    public static void main(String[] args) {
//        创建TreeSet集合对象,无参构造
        TreeSet<Student> ts=new TreeSet<Student>();
//        创建Student对象
        Student s1=new Student("xiyangyang",19);
        Student s2=new Student("lanyangyang",15);
        Student s3=new Student("meiyangyang",18);
        Student s4=new Student("feiyangyang",20);
//        将学生对象添加到集合
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
//        使用循环遍历集合
        for (Student s:ts){
            System.out.println(s.getName()+","+s.getAge());
        }
    }
}
 
观察第二段代码会发现,遍历的时候出现了错误
 
也就是类类型转化异常,所以我们直接遍历显然是不行的
 这里需要查看帮助文档对Student类进行操作。
 
上述文字也告诉我们,使用无参构造进行自然排序,插入到集合中的元素必须实现Comparable接口
 随便观察JDK有的类可以发现
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence,Constable, ConstantDesc 
    {
     	……
	}
 
public final class Integer extends Number
        implements Comparable<Integer>, Constable, ConstantDesc 
        {
        ……
        }
 
他们都实现了Comparable接口,所以咱们写的时候他自个儿排好序了
 可是要是在集合中添加自定义类,不实现Comparable接口,就会报出类类型转化异常的错误
那好说,实现就行了,所以我们需要在Student类里implements一下Comparable接口
 
Comparable接口里只有一个抽象方法需要实现——compareTo
 所以在Student类里重写compareTo方法就大功告成了
也就是这样
package myCollection.set02;
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;
    }
    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 int compareTo(Student s) {
    //默认生成的
        return 0;
    }
}
 
这个时候再运行一下,会发现四个学生对象只存储进去了一个
 
我们再来细品一下compareTo()方法,compareTo()方法用于对元素之间比较
对于表达式 x.compareTo(y)
 如果返回0,表示x==y
 如果返回值 >0 表示 x > y
 如果返回值 <0 表示 x < y
这个时候,就需要对compareTo()进行加工了
package myCollection.set02;
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;
    }
    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 int compareTo(Student s) {
//        this是调用该方法的对象,也就是当前对象   s是之前的对象
//        比较年龄,如果后一个比前一个大,返回值大于0进行,升序排列
        int num = this.age - s.age;
        int num2 = num == 0 ? this.name.compareTo(s.name) : num;
        return num2;
    }
}
 
现在年龄已经按照升序的方式排序了
当年龄一样的时候,会返回0,这个时候对名字的内容进行排序,按照字典的顺序
package myCollection.set02;
import java.util.TreeSet;
public class TreeSetDemo {
    public static void main(String[] args) {
//        创建TreeSet集合对象,无参构造
        TreeSet<Student> ts=new TreeSet<Student>();
//        创建Student对象
        Student s1=new Student("xiyangyang",19);
        Student s2=new Student("lanyangyang",15);
        Student s3=new Student("meiyangyang",18);
        Student s4=new Student("nicaiyangyang",20);
        Student s5=new Student("feiyangyang",20);
//        将学生对象添加到集合
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
//        使用循环遍历集合
        for (Student s:ts){
            System.out.println(s.getName()+","+s.getAge());
        }
    }
}
 
如果想对年龄进行降序排序,同样需要修改返回值
package myCollection.set02;
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;
    }
    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 int compareTo(Student s) {
//        this是调用该方法的对象,也就是当前对象   s是之前的对象
//        比较年龄,如果后一个比前一个大,返回值大于0进行,升序排列
        int num = this.age - s.age;
        int num2 = num == 0 ? this.name.compareTo(s.name) : num;
        return num2;
    }*/
    @Override
    public int compareTo(Student s) {
//    比较年龄,前一个比后一个大 前一个就在前面进行降序排列
        int num = s.age - this.age;
        return num;
    }
}
 

带参构造 | 定制排序
带参构造,需要实现Comparator接口
 
此时,在没有让Student类实现Comparable接口时,可以使用带参构造创建匿名内部类
在带参的参数括号里创建一个子类对象,实现Comparator接口
package myCollection.set02;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
    public static void main(String[] args) {
//        创建TreeSet集合对象,带参构造
        TreeSet<Student> ts=new TreeSet<Student>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
//                o1为当前对象 o2为之前的对象
//                年龄升序
                int num = o1.getAge() - o2.getAge();
                int num2 = num == 0 ? o1.getName().compareTo(o2.getName()) : num;
                return num2;
            }
        });
//        创建Student对象
        Student s1=new Student("xiyangyang",19);
        Student s2=new Student("lanyangyang",15);
        Student s3=new Student("meiyangyang",18);
        Student s4=new Student("nicaiyangyang",20);
        Student s5=new Student("feiyangyang",20);
//        将学生对象添加到集合
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
//        使用循环遍历集合
        for (Student s:ts){
            System.out.println(s.getName()+","+s.getAge());
        }
    }
}
 











