TreeSet支持2种排序:自然排序、比较器排序。
由于TreeSet对内部元素的排序的方法有2种:自然顺序排序、比较器排序。 所以,如果TreeSet采用自然顺序排序,需要内部的元素(即自定义类型)实现Comparable接口。 如果TreeSet采用比较器排序,需要提供比较器对象。
自然排序:被放入TreeSet的数据,必须实现Comparable接口。Comparable接口中只有一个方法compareTo(T t) ,即被放入TreeSet中的对象要实现compareTo方法,TreeSet每放入一个元素,就会拿这个元素和已有元素比较(用compareTo方法比较),最终确定新添加的数据的位置,使TreeSet集合所有元素有序。
比较器排序:这种排序方式更加灵活,不要求容器中的元素实现Comparable接口。而是通过一个实现了Comparator接口的类来对TreeSet中的元素进行排序。Comparator实现类必须要实现 compare(Tt1, T t2)方法。TreeSet中每放入一个元素,就会借助比较器比较新加入的元素和已有元素的大小关系,最终确定新添加的数据的位置,使TreeSet集合所有元素有序。
自然排序
创建一个Teacher类,做自然排序.
public class Teacher implements Comparable<Teacher>{
private int age;
private String name;
private int salary;
public Teacher() {
}
public Teacher(int age, String name, int salary) {
this.age = age;
this.name = name;
this.salary = salary;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Teacher{" +
"age=" + age +
", name='" + name + '\'' +
", salary=" + salary +
'}';
}
@Override
public int compareTo(Teacher o) {
//年龄升序,如果年龄相等按工资降序
if (this.age-o.age!=0){
return this.getAge()-o.getAge();
}else {
return o.salary-this.salary;
}
}
}
比较器排序
创建一个Teacher1,做比较器排序.
public class Teacher1 {
private int age;
private String name;
private int salary;
public Teacher1() {
}
public Teacher1(int age, String name, int salary) {
this.age = age;
this.name = name;
this.salary = salary;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Teacher{" +
"age=" + age +
", name='" + name + '\'' +
", salary=" + salary +
'}';
}
}
实现两种排序
创建一个TestTeacher类,用来实现两种排序,进行比较两种排序.
import java.util.Comparator;
import java.util.TreeSet;
public class TestTeacher {
public static void main(String[] args) {
TreeSet<Teacher> set=new TreeSet<>();
Teacher t1=new Teacher(24,"王老师",1500);
Teacher t2=new Teacher(18,"张老师",3500);
Teacher t3=new Teacher(24,"赵老师",2500);
Teacher t4=new Teacher(19,"李老师",4500);
set.add(t1);
set.add(t2);
set.add(t3);
set.add(t4);
System.out.println("Comparable的排序结果:");
System.out.println(set);
System.out.println("--------------------------------------------");
Teacher1 tt1=new Teacher1(24,"王老师",1500);
Teacher1 tt2=new Teacher1(18,"张老师",3500);
Teacher1 tt3=new Teacher1(24,"赵老师",2500);
Teacher1 tt4=new Teacher1(19,"李老师",4500);
TreeSet<Teacher1> set1=new TreeSet<>(new Comparator<Teacher1>() {
@Override
public int compare(Teacher1 o1, Teacher1 o2) {
//如果两个对象中属性数值相等(age相等或工资相等...),那么后一个对象就添加不上,所以要判断一下相等的情况;
if (o1.getAge()-o2.getAge()!=0){
return o1.getAge()-o2.getAge();
}else {
return o2.getSalary()-o1.getSalary();
}
}
});
set1.add(tt1);
set1.add(tt2);
set1.add(tt3);
set1.add(tt4);
System.out.println("Comparator的排序结果:");
System.out.println(set1);
}
}
结果:
总结:
自然排序Comparable和比较器Comparator可以实现一样的效果,但两种排序也有一些区别:
实现Comparable在实体类中实现,方便创建异常排序条件,多次使用。
实现Comparable排序条件固化,不便于条件的改变
实现Comparator可以在每次创建对象使用时,重写排序条件,较为复杂,不利于多次使用
实现Comparator排序条件灵活,便于条件的随时改变。