1:比较和排序的概念

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

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

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

2:Comparable与Comparator

but,在软件开发的世界中,任何没有代码的堆概念都是耍流氓。所以,无论我们解释的多么完美,必须show me the code;

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

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

Comparable与Comparator,java中的排序与比较的更多相关文章

  1. Java中的排序算法(2)

    Java中的排序算法(2) * 快速排序 * 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists). * 步骤为: * 1. 从数 ...

  2. Java中List排序的3种方法

    在某些特殊的场景下,我们需要在 Java 程序中对 List 集合进行排序操作.比如从第三方接口中获取所有用户的列表,但列表默认是以用户编号从小到大进行排序的,而我们的系统需要按照用户的年龄从大到小进 ...

  3. [个人原创]关于java中对象排序的一些探讨(一)

    有的时候我们需要将自己定义的对象,有序输出.因为一般我们程序的中间结果需要存储在容器里,那么怎样对容器中的对象按照一定次序输出就是程序员经常需要考虑的问题.本片文章探讨了怎样有序化输出容器中的对象的问 ...

  4. Java中中文排序器

    在Java中使用Collator类按照汉字拼音排序字符串 public static void main(String[] args) throws Exception{ String[] strs ...

  5. java中的排序--排序容器_TreeSet与TreeMap

    1.TreeSet:数据元素可以排序且不可重复. 对比: (1)Set接口:HashSet,元素必须重写hashcode和equals方法. (2)TreeSet:只要可以排序即可.去重:比较等于0即 ...

  6. java中的排序(自定义数据排序)--使用Collections的sort方法

    排序:将一组数据按相应的规则 排列 顺序 1.规则:       基本数据类型:日常的大小排序. 引用类型: 内置引用类型(String,Integer..),内部已经指定规则,直接使用即可.---- ...

  7. JAVA中List 排序

    第一种方法,就是list中对象实现Comparable接口,代码如下: public class SortEntity implements Comparable<SortEntity>{ ...

  8. [个人原创]关于java中对象排序的一些探讨(三)

    这篇文章由十八子将原创,转载请注明,并标明博客地址:http://www.cnblogs.com/shibazijiang/ 对对象排序也可以使用Guava中的Ordering类. 构造Orderin ...

  9. java中的排序

    排序是数据结构中重要的一个部分,也是在实际开发中最易遇到的问题之一,当然了,你也可以不考虑这些排序的算法,直接把要排序的数据insert到数据库中,用数据库的order by再select一下,也能产 ...

随机推荐

  1. 1000行代码徒手写正则表达式引擎【1】--JAVA中正则表达式的使用

    简介: 本文是系列博客的第一篇,主要讲解和分析正则表达式规则以及JAVA中原生正则表达式引擎的使用.在后续的文章中会涉及基于NFA的正则表达式引擎内部的工作原理,并在此基础上用1000行左右的JAVA ...

  2. 网页标题title的闪动提示

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  3. jquery取出所有包含class='engineer_val'的值

    $(".engineer_val").each(function(){ //jquery取出所有包含class='engineer_val'的值 $(); });

  4. 7.java的请求转发和请求重定向

    1.请求重定向:是客户端的行为,response.sendRedirect(),从本质上讲等同于两次请求,前一次的请求对象不会保存,地址栏的URL地址会改变,一次新的转发. 2.请求转发:是服务器的行 ...

  5. ListView 介绍

    1. 通过继承Activity实现ListView 1.1 在XML布局文件中实现一个ListView <ListView android:layout_width="wrap_con ...

  6. css画三角形,梯形

    (根据调节边框的宽度来调节三角形形状) <!DOCTYPE html> <html> <head> <meta http-equiv="Conten ...

  7. 使用python操作mysql数据库

    这是我之前使用mysql时用到的一些库及开发的工具,这里记录下,也方便我查阅. python版本: 2.7.13 mysql版本: 5.5.36 几个python库 1.mysql-connector ...

  8. 在线用户数-Constants

    package com.pb.news.constants; public class Constants { public static int ONLINE_USER_COUNT=0;//在线用户 ...

  9. file里的路径

    实例话file类的对象 File file=new File("d:/mydoc/hello.txt") 文件名:fileMethod.java 相对路径:fileMethod.j ...

  10. usaco 2002 月赛 Fiber Communications 题解

    Description Farmer John wants to connect his N (1 <= N <= 1,000) barns (numbered 1..N) with a ...