Java基础类库--比较器

内容学习于:edu.aliyun.com


1. 比较器问题引出

  所谓的比较器指的就是进行大小关系的确定判断,下面首先来分析一下比较器存在的意义。
  如果要进行数组操作,肯定使用java.util.Arrays的操作类完成,这个类里面提供有绝大部分的数组操作支持,同时在这个类里面还提供有一种对象数组的排序支持: public static void sort(Object[] a);

对象数组排序代码:

public class JavaAPIDemo {
    public static void main(String[] args) {
        Integer data[] = new Integer[]{10, 9, 5, 2, 20};//对象数组
        Arrays.sort(data);//进行对象数组排序
        System.out.println(Arrays.toString(data));
    }
}

结果:

[2, 5, 9, 10, 20]

字符数组排序:

public class JavaAPIDemo {
    public static void main(String[] args) {
        String data[] = new String[]{"X", "K", "O", "P", "C"};//对象数组
        Arrays.sort(data);//进行对象数组排序
        System.out.println(Arrays.toString(data));
    }
}

结果:

[C, K, O, P, X]

代码:

class Person {
    private String name;
    private int age;

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

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

    //无参构造、setter、getter省略
}

public class JavaAPIDemo {
    public static void main(String[] args) {
        Person[] data = new Person[]{
                new Person("小明-A", 100),
                new Person("小明-B", 80),
                new Person("小明-C", 90)
        };//对象数组
        Arrays.sort(data);//进行对象数组排序
        System.out.println(Arrays.toString(data));
    }
}

结果:

Exception in thread “main” java.lang.ClassCastException: class com.xzzz.e20200114_chapter1.Person cannot be cast to class java.lang.Comparable

  <mark>任意的一个类默认情况下是无法使用系统内部的类实现数组排序或比较需求的</mark>,是因为没有明确的指定出到底该如何进行比较的定义(没有比较规则),那么这个时候在Java里面为了统一比较规则的定义,所以提供有比较器的接口: Comparable 接口

2. Comparable比较器

  通过分析可以发现如果要实现对象的比较肯定需要有比较器来制定比较规则,而比较的规则就通过Comparable来实现,对于Comparable而言,需要清楚其基本的定义结构:

定义:

public interface Comparable<T>{
    /** * 实现对象的比较处理操作 * @param o 要比较的对象 * @return 当前数据比传入的对象小返回负数,如果大于返回正数,如果等于返回0 */
    public int compareTo(T o);
}

  如下图所示:

实现自定义比较操作:

class Person implements Comparable<Person> {
    private String name;
    private int age;

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

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

    @Override
    public int compareTo(Person per) {
        return this.age - per.age;
    }

    //无参构造、setter、getter省略
}

public class JavaAPIDemo {
    public static void main(String[] args) {
        Person[] data = new Person[]{
                new Person("小明-A", 100),
                new Person("小明-B", 80),
                new Person("小明-C", 90)
        };//对象数组
        Arrays.sort(data);//进行对象数组排序
        System.out.println(Arrays.toString(data));
    
}

结果:

[Person{name=‘小明-B’, age=80}
, Person{name=‘小明-C’, age=90}
, Person{name=‘小明-A’, age=100}
]

  排序里面只需要有一个compareTo()方法进行排序规则的定义,而后整个Java系统里面就可以为其实现排序处理了。

3. Comparator比较器(定义了函数式接口)

  Comparator属于一种挽救的比较器支持,其主要的目的是解决一些没有使用Comparable排序的类的对象数组排序。

比较方法:int compare(T o1,T o2)

  后来经过了若干版本的迭代更新之后发现需要对Person类进行排序处理,但是又不能够去修改Person类(无法实现Comparable接口),所以这个时候就需要采用一种挽救的形式来实现比较,在Arrays类里面排序有另外一种实现:
基于Comparator的排序处理: public static void sort(T[] a, Comparator<? super T>c)
  如下图所示:
  在java.util.Comparator里面最初只定义有一个排序的compare(方法(public int compare(T o1, T o2)),但是后来持续发展又出现了许多的static方法。

实现排序代码:

class PersonComparator implements Comparator<Person> {

    @Override
    public int compare(Person p1, Person p2) {
        return p1.getAge() - p2.getAge();
    }
}

class Person {
    private String name;
    private int age;

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

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


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

public class JavaAPIDemo {
    public static void main(String[] args) {
        Person[] data = new Person[]{
                new Person("小明-A", 100),
                new Person("小明-B", 80),
                new Person("小明-C", 90)
        };//对象数组
        Arrays.sort(data, new PersonComparator());//进行对象数组排序
        System.out.println(Arrays.toString(data));
    }
}

结果:

[Person{name=‘小明-B’, age=80}
, Person{name=‘小明-C’, age=90}
, Person{name=‘小明-A’, age=100}
]

  <mark>对于这种排序的操作如果不是必须的情况下强烈不建议使用Comparator,最好以Comparable为主。</mark>

  <mark>面试题:请解释Comparable与Comparator的区别?</mark>

  java.lang.Comparable是在类定义的时候实现的父接口,主要用于定义排序规则,里面只有一个compareTo()方法;
  java.util.Comparator 是挽救的比较器操作,需要设置单独的比较器规则类实现排序,里面有compare()方法。

全部评论

相关推荐

2025-11-04 21:22
天津理工大学 Java
Tom哥981:让我来压力你!!!: 这份简历看着“技术词堆得满”,实则是“虚胖没干货”,槽点一抓一大把: 1. **项目描述是“技术名词报菜名”,没半分自己的实际价值** 不管是IntelliDoc还是人人探店,全是堆Redis、Elasticsearch、RAG这些时髦词,但你到底干了啥?“基于Redis Bitmap管理分片”是你写了核心逻辑还是只调用了API?“QPS提升至1500”是你独立压测优化的,还是团队成果你蹭着写?全程没“我负责XX模块”“解决了XX具体问题”,纯把技术文档里的术语扒下来凑字数,看着像“知道名词但没实际动手”的实习生抄的。 2. **短项目塞满超纲技术点,可信度直接***** IntelliDoc就干了5个月,又是RAG又是大模型流式响应又是RBAC权限,这堆活儿正经团队分工干都得小半年,你一个后端开发5个月能吃透这么多?明显是把能想到的技术全往里面塞,生怕别人知道你实际只做了个文件上传——这种“技术堆砌式造假”,面试官一眼就能看出水分。 3. **技能栏是“模糊词混子集合”,没半点硬核度** “熟悉HashMap底层”“了解JVM内存模型”——“熟悉”是能手写扩容逻辑?“了解”是能排查GC问题?全是模棱两可的词,既没对应项目里的实践,也没体现深度,等于白写;项目里用了Elasticsearch的KNN检索,技能栏里提都没提具体掌握程度,明显是“用过但不懂”的硬凑。 4. **教育背景和自我评价全是“无效信息垃圾”** GPA前10%这么好的牌,只列“Java程序设计”这种基础课,分布式、微服务这些后端核心课提都不提,白瞎了专业优势;自我评价那堆“积极认真、细心负责”,是从招聘网站抄的模板吧?没有任何和项目挂钩的具体事例,比如“解决过XX bug”“优化过XX性能”,纯废话,看完等于没看。 总结:这简历是“技术名词缝合怪+自我感动式凑数”,看着像“背了后端技术栈名词的应届生”,实则没干货、没重点、没可信度——面试官扫30秒就会丢一边,因为连“你能干嘛”都没说清楚。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务