TreeSet集合 | 自然排序&定制排序

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());
        }

    }
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值