TreeSet的两种排序方式:自然排序和定制排序

时间:2021-01-11 12:40:41

TreeSet的两种排序方式:自然排序和定制排序

TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。TreeSet有两种排序方法:自然排序和定制排序。默认采用自然排序。

1. 自然排序

要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)的抽象方法在此方法中,指明按照自定义类的哪个属性进行排序。向TreeSet中添加元素时,首先按照compareTo()进行比较,一旦返回0,虽然仅是两个对象的此属性值相同,但是程序会认为这两个对象是相同的,进而后一个对象就不能添加进来。因此要求compareTo()与hashCode()以及equals()三者保持一致!

1.1 定义一个学生类

//定义一个学生类
public class Student implements Comparable{

    private String name;
    private Integer age;
    public Student() {
        super();
    }
    public Student(String name, Integer age) {
        super();
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((age == null) ? 0 : age.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age == null) {
            if (other.age != null)
                return false;
        } else if (!age.equals(other.age))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    //当向TreeSet中添加Student类的对象时,依据此方法,确定按照哪个属性排列。
    //先按照年龄进行排序,如果年龄相等再按姓名排序
    @Override
    public int compareTo(Object o) {
        if(o instanceof Student){
            Student student = (Student) o;
            int i = this.age.compareTo(student.age);
            if(i == 0){
                return this.name.compareTo(student.name);
            }else{
                return i;
            }
        }
        return 0;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }
}

1.2 向TreeSet中添加元素

//自然排序
@Test
public void test1(){
    Set<Student> set = new TreeSet<Student>();
    set.add(new Student("张飞", 27));
    set.add(new Student("关羽", 28));
    set.add(new Student("刘备", 27));
    set.add(new Student("吕布", 29));
    set.add(new Student("赵子龙", 30));

    for(Object obj : set){
        System.out.println(obj);
    }
}

1.3 运行效果

TreeSet的两种排序方式:自然排序和定制排序

2. 定制排序

//定制排序
    @Test
    public void test2(){
        //1.创建一个实现了Comparator接口类的对象
        Comparator<Student> com = new Comparator<Student>() {
            //2.向TreeSet中添加Student类的对象,在此compare()方法中,指明是按照Customer的哪个属性进行排序的
            @Override
            public int compare(Student o1, Student o2) {
                if(o1 instanceof Student && o2 instanceof Student){
                    Student stu1 = (Student)o1;
                    Student stu2 = (Student)o2;
                    int i = stu1.getAge().compareTo(stu2.getAge());
                    if(i == 0){
                        return stu1.getName().compareTo(stu2.getName());
                    }
                    return i;
                }
                return 0;
            }
        }; 
        //3.将此对象作为形参传递给TreeSet的构造器中
        TreeSet<Student> set = new TreeSet<Student>(com);
        //4.向TreeSet中添加Comparator接口中的compare方法中涉及的类的对象。
        set.add(new Student("张飞", 27));
        set.add(new Student("关羽", 28));
        set.add(new Student("刘备", 27));
        set.add(new Student("吕布", 29));
        set.add(new Student("赵子龙", 30));
        set.add(new Student("曹操", 40));
        set.add(new Student("周瑜", 30));
        set.add(new Student("诸葛亮", 30));

        for(Object obj : set){
            System.out.println(obj);
        }
    }

* 运行效果 *
TreeSet的两种排序方式:自然排序和定制排序

注意:纯属个人理解,如果存在有误,请指正!