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

相关推荐
CC城子2 小时前
EtherCAT的igh学习与研究(二)
学习·ethercat
炽烈小老头3 小时前
【每天学习一点算法 2026/04/11】Pow(x, n)
学习·算法
旖-旎3 小时前
哈希表(存在重复元素)(3)
数据结构·c++·学习·算法·leetcode·散列表
weixin_513449963 小时前
walk_these_ways项目学习记录第九篇(通过行为多样性 (MoB) 实现地形泛化)--学习算法
学习·算法·机器学习
chh5634 小时前
C++--内存管理
java·c语言·c++·windows·学习·面试
CNemon4 小时前
《怎样学习文言文》溯源
学习
wayz114 小时前
21天机器学习核心算法学习计划(量化方向)
学习·算法·机器学习
Flandern11114 小时前
Go程序员学习AI大模型项目实战02:给 AI 装上“大脑”:从配置解包到流式生成的深度拆解
人工智能·后端·python·学习·golang
weixin_513449964 小时前
walk_these_ways项目学习记录第十篇(通过行为多样性 (MoB) 实现地形泛化)--从仿真到部署
人工智能·学习·算法