JavaSE学习——比较相关接口

很多类里面有compareTo方法,这个方法是源于comparable接口里。Arrays可以调用sort方法,前提是这个数组类型实现了comparable方法。

比如下面的代码是不对的,因为Student类并没有实现comparable接口,所以数组不知道明确的比较规则而报错:

复制代码
public class Main {
    public static void main(String[] args){
        Student[] stu = {new Student(), new Student()};
        Arrays.sort(stu);
    }
    static class Student{ }
}

现在为Student类里实现Comparable接口:

复制代码
static class Student implements Comparable<Student>{
    int age;

    public Student(int age) {
        this.age = age;
    }

    @Override
    public int compareTo(Student o) {
        return age - o.age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                '}';
    }
}

有了比较的方法,就可以进行排序;

java 复制代码
    public static void main(String[] args){
        TreeSet set = new TreeSet<>();
        set.add(new Student(10));
        set.add(new Student(16));
        System.out.println(set);
    }
java 复制代码
public static void main(String[] args){
        Student[] arr = {new Student(6),new Student(9),new Student(8)};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
    }

此外,如果在Student类并没有实现Comparable方法,也可以在调用Arrays.sort()的时候使用lambda表达式去添加。比如:

复制代码
public static void main(String[] args){
    Student[] arr = {new Student(6),new Student(9),new Student(8)};
    Arrays.sort(arr, (s1,s2)->s1.age-s2.age);   //比较方法
    System.out.println(Arrays.toString(arr));
}
static class Student{
    int age;

    public Student(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                '}';
    }
}

在TreeSet里面,也可以定义比较方法:

复制代码
TreeSet<Student> stu = new TreeSet<>((s1,s2)->s1.age - s2.age);
stu.add(new Student(6));
stu.add(new Student(9));
System.out.println(stu);

此外,可以单独写一行定义comparator,这样就直接传入:(reversed是在原来的基础上取反)

复制代码
Comparator<Student> comparator = (s1,s2)->s1.age - s2.age;
TreeSet<Student> stu = new TreeSet<>(comparator.reversed());

现在,我们除了需要比较年龄来排序,还要一个额外的姓名排序(即年龄一样,按照姓名排序),使用thenComparing(),下面是Student类:

复制代码
static class Student{
    int age;
    String name;

    public Student(int age,String name) {
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

下面是主文件:

复制代码
Comparator<Student> comparator = (s1,s2)->s1.age - s2.age;
TreeSet<Student> stu = new TreeSet<>(comparator.thenComparing((s1,s2)->s1.name.compareTo(s2.name)));
stu.add(new Student(6,"hxl"));
stu.add(new Student(6,"lhw"));
stu.add(new Student(8,"520"));
System.out.println(stu);

此外,thenComparing也可以:

复制代码
Comparator<Student> comparator = (s1,s2)->s1.age - s2.age;
TreeSet<Student> stu = new TreeSet<>(comparator.thenComparing(
        s->s.name,
        (n1,n2)->n1.compareTo(n2))
);

thenComparing还可以更加精简,因为上面使用的也是字符串默认的比较方式:

复制代码
TreeSet<Student> stu = new TreeSet<>(comparator.thenComparing(
        s->s.name)
);

还有比较规则对于空值的处理:

复制代码
reeSet<Integer> set = new TreeSet<>(Comparator.nullsFirst(Comparator.naturalOrder()));

nullsFirst表示如果传入值为null,比较级优先。naturalOrder表示默认的比较(从小到大)

复制代码
set.add(5);
set.add(1);
set.add(2);
set.add(null);
System.out.println(set);

也可以这样写

复制代码
TreeSet<Student> stu = new TreeSet<>(Comparator.comparing(s->s.age));

总结:

Comparator是类外面手动定义的一个比较规则,Comparable是类内部自行定义的衣服比较规则。

相关推荐
我的xiaodoujiao1 天前
API 接口自动化测试详细图文教程学习系列16--项目实战演练3
python·学习·测试工具·pytest
复利人生 复利日知录 赋能循环1 天前
2026年复利精进:我的每日觉醒与成长密码
学习·思维模型·知识复利·复利·独立
sakiko_1 天前
UIKit学习笔记4-使用UITableView制作滚动视图
笔记·学习·ios·swift·uikit
晓梦林1 天前
MAZESEC-X1靶场学习笔记
笔记·学习
我的xiaodoujiao1 天前
API 接口自动化测试详细图文教程学习系列15--项目实战演练2
python·学习·测试工具·pytest
TImCheng06091 天前
职场人AI学习周期评估:不同学习路径的时间成本
人工智能·学习
周末也要写八哥1 天前
C4D/Cinema 4D 2026超详细下载与安装教程(附资源包)
学习·数学建模
xinzheng新政1 天前
openclaw dashboard报错 internal server error
学习
nashane1 天前
HarmonyOS 6学习:RichEditor宽度“暴力”计算与富文本截图避坑
学习·harmonyos 5
鹿鸣悠悠1 天前
【AI学习】全链路、并发、响应时间
学习