Comparable与Comparator,java中的排序与比较

简介: 1:比较和排序的概念     比较:两个实体类之间按>,=, student.age)        {            return 1;        }        else if (age == student.

1:比较和排序的概念

    比较:两个实体类之间按>,=,<进行比较。

    排序:在集合类中,对集合类中的实体进行排序。排序基于的算法基于实体类提供的比较函数。

    基本型别都提供了默认的比较算法,如string提供了按字母进行比较,int提供了按整数大小进行比较。

 

2:Comparable与Comparator

but,光看概念没有任何意义,我们不知道这对代码来说意味着什么;

我们首先看这样一段代码:

public class CollectorTest {
    public static void main(String[] args) {

        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("a", 3));
        students.add(new Student("c", 2));
        students.add(new Student("b", 1));
        students.add(new Student("d", 4));
        for (Student student : students) {
            System.out.printf("name:%s, age: %d \n", student.name, student.age);
        }
    }
}

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

 

以上是创建了四个学生,并遍历一遍。但是现在我们需要按年龄大小进行遍历,怎么办?这个时候排序接口就发挥作用了。可以为Student提供排序的接口Comparable,如下,

public class CollectorTest {
    public static void main(String[] args) {

        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("a", 3));
        students.add(new Student("c", 2));
        students.add(new Student("b", 1));
        students.add(new Student("d", 4));
        Collections.sort(students);
        for (Student student : students) {
            System.out.printf("name:%s, age: %d \n", student.name, student.age);
        }
    }
}

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

    @Override
    public int compareTo(Object o) {
        Student student = (Student)o;
        if (age> student.age)
        {
            return 1;
        }
        else if (age == student.age)
        {
            return 0;
        }
        else
        {
            return -1;
        }
        //return Integer.valueOf(age).compareTo(Integer.valueOf(student.age));
    }
}

输出的结果为:

name:b, age: 1
name:c, age: 2
name:a, age: 3
name:d, age: 4

很棒。PS:注意排序方法中最后被注释掉的一行,排序方法中的逻辑可以被这一行代替,只不过为了给大家演示期间,我还原了这个Integer的compareTo方法。

现在问题来了,我不想用年龄进行排序了,我想用姓名进行排序,该怎么办?要知道我们只能实现一个排序接口,排序接口只有一个方法。这个时候,比较器就派上用场了!

我们实现一个name的比较器,如下:

public class CollectorTest {
    public static void main(String[] args) {

        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("a", 3));
        students.add(new Student("c", 2));
        students.add(new Student("b", 1));
        students.add(new Student("d", 4));
        //Collections.sort(students);
        students.sort(new NameSorter());
        for (Student student : students) {
            System.out.printf("name:%s, age: %d \n", student.name, student.age);
        }
    }
}

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

    @Override
    public int compareTo(Object o) {
        Student student = (Student)o;
        if (age> student.age)
        {
            return 1;
        }
        else if (age == student.age)
        {
            return 0;
        }
        else
        {
            return -1;
        }
        //return Integer.valueOf(age).compareTo(Integer.valueOf(student.age));
    }
}

class NameSorter implements Comparator{

    @Override
    public int compare(Object o1, Object o2) {
        Student s1 =(Student) o1;
        Student s2 =(Student) o2;
        return s1.name.compareTo(s2.name);
    }
}

现在的结果:

name:a, age: 3
name:b, age: 1
name:c, age: 2
name:d, age: 4

将来我们要按照性别,按照学生成绩排序,可能还会有更多更多的排序的要求,那就去实现更多的比较器就行了。

 

3:Comparable与Comparator的泛型版本Comparable<T>与Comparator<T>

如果我们稍有经验,我们就会发现上面的代码的接口Comparable与Comparator都是已经不建议使用了。当泛型出来后,所有非泛型集合类和接口都已经建议尽量不使用了。至于原因,从上面的代码中我们也可以看出一点端倪。

注意查看compare函数,如:

Student s1 =(Student) o1;
Student s2 =(Student) o2;

我们发现这个函数进行了装箱和拆箱。而这是会影响性能的。如果我们的集合中有成千上万个复杂的实体对象,则在排序的时候所耗费掉的性能就是客观的。而泛型的出现,就可以避免掉拆箱和装箱。

故,我们就该实现Comparable<T>与Comparator<T>。最终的代码如下:

package com.zuikc.se.collectors;

/**
* 排序和比较器的用法,Comparable与Comparator,java中的排序与比较
* author:最课程(zuikc.com)
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class CollectorTest {
    public static void main(String[] args) {

        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("a", 3));
        students.add(new Student("c", 2));
        students.add(new Student("b", 1));
        students.add(new Student("d", 4));
        //Collections.sort(students);
        students.sort(new NameSorter());
        for (Student student : students) {
            System.out.printf("name:%s, age: %d \n", student.name, student.age);
        }
    }
}

class Student implements Comparable<Student>{
    public String name;
    public int age;
    public Student(String name, int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Student student) {
        if (age> student.age)
        {
            return 1;
        }
        else if (age == student.age)
        {
            return 0;
        }
        else
        {
            return -1;
        }
        //return Integer.valueOf(age).compareTo(Integer.valueOf(student.age));
    }
}

class NameSorter implements Comparator<Student>{

    @Override
    public int compare(Student s1, Student s2) {
        return s1.name.compareTo(s2.name);
    }
}

Creative Commons License本文基于 Creative Commons Attribution 2.5 China Mainland License发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 http://www.cnblogs.com/luminji(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。
目录
相关文章
|
2月前
|
存储 搜索推荐 算法
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
33 1
|
4月前
|
Java API
|
5月前
|
Java API 存储
Java如何对List进行排序?
【7月更文挑战第26天】
267 9
Java如何对List进行排序?
|
4月前
|
存储 Java
Java中ArrayList 元素的排序
本文提供了Java中根据`ArrayList`元素的某个属性进行排序的示例代码,包括实现`Comparable`接口和重载`compareTo`方法,然后使用`Collections.sort`方法进行排序。
|
4月前
|
存储 Java API
【Java高手必备】揭秘!如何优雅地对List进行排序?掌握这几种技巧,让你的代码瞬间高大上!
【8月更文挑战第23天】本文深入探讨了Java中对List集合进行排序的各种方法,包括使用Collections.sort()、自定义Comparator以及Java 8的Stream API。通过示例代码展示了不同情况下如何选择合适的方法:从简单的整数排序到自定义类对象的排序,再到利用Comparator指定特殊排序规则,最后介绍了Stream API在排序操作中的简洁应用。理解这些技术的区别与应用场景有助于提高编程效率。
129 4
|
4月前
|
搜索推荐 算法 Java
堆排序实战:轻松实现高效排序,附详细Java代码
嗨,大家好!我是小米,一名热爱技术分享的程序员。今天要带大家了解堆排序——一种基于二叉堆的数据结构,具有O(n log n)时间复杂度的选择排序算法。堆排序分为构建大顶堆和排序两个阶段:先建堆使根节点为最大值,再通过交换根节点与末尾节点并调整堆来逐步排序。它稳定高效,空间复杂度仅O(1),适合对稳定性要求高的场合。虽然不如快速排序快,但在避免递归和节省空间方面有优势。一起动手实现吧!如果有任何疑问,欢迎留言交流!
99 2
|
4月前
|
存储 Java
|
4月前
|
Java 容器
07 Java数组与数组操作(定义+遍历+排序+增删改查)(上)
07 Java数组与数组操作(定义+遍历+排序+增删改查)
63 8
|
4月前
|
存储 Java API
07 Java数组与数组操作(定义+遍历+排序+增删改查)(下)
07 Java数组与数组操作(定义+遍历+排序+增删改查)
45 4
|
4月前
|
存储 Java