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是类内部自行定义的衣服比较规则。

相关推荐
差不多的周周3 小时前
《骨架上下文:基于零镜头骨架的动作识别的骨架侧上下文提示学习》论文核心部分详解
学习
Century_Dragon4 小时前
从挂图到VR:汽修专业的一堂新能源原理课可以怎么上~
学习
知识分享小能手5 小时前
C++ 学习教程,从入门到精通,C++对象和类 — 详细知识点总结(10)
开发语言·c++·学习
New农民工6 小时前
倒立摆训练秘籍:理解训练参数
学习
L@ncor6 小时前
第五章 基于低代码平台的智能体搭建 · 学习笔记(Coze / Dify / FastGPT / n8n)
笔记·学习·低代码·agent·prompt工程
迪丽热爱6 小时前
多媒体应用20-903(补)
学习
传奇开心果编程8 小时前
【Flutter入门练中学】第8课:动画与过渡
android·学习·flutter·ui·ios
程序员yu9 小时前
会编网络:别被入门教程骗了,Python实用能力不在语法本身
开发语言·python·学习·算法
Lintongzg9 小时前
千卡训练的隐形账单:通信不是瓶颈
笔记·学习·性能优化·llm
dadaobusi9 小时前
学习: SIOV
学习