Java比较器

来源:互联网 发布:dnf优化后盒子无法换装 编辑:程序博客网 时间:2024/06/06 18:14
当我们要对一组数字进行排序的时候,可以写一个排序算法实现;如果要对字母进行排序的时候,则通过26个字母的自然顺序进行排序。

但是,当需要排序的集合或数组不是单纯的数字类型时,我们通常使用ComparatorComparable,以简单的方式实现对象排序或自定义排序。


1.Comparable内部比较器,此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo 方法被称为它的自然比较方法。


2.Comparator外部比较器,是T - 此 Comparator 可以比较的对象类型,它是强行对某个对象collection 进行整体排序 的比较函数。


3.区别:
Comparable 用作默认的比较方式 。
Comparator 用作自定义的比较方式,当默认的比较方式不适用时或者没有提供默认的比较方式,使用Comparator就非常有用。
Comparator 强行对某个对象collection进行整体排序的比较函数,可以将Comparator传递给Collections.sortArrays.sort
Comparable强行对实现它的每个类的对象进行整体排序,实现此接口的对象列表(和数组)可以通过Collections.sorArrays.sort进行自动排序。


4.用法:

1、内部比较器:java.lang.Comparable<T> 接口声明了:int compareTo(T o) 方法 
  比较此对象与执行对象的顺序。比较规则同上,即: 
  1)如果此对象大于指定对象,返回正整数 ;
  2)如果此对象小于指定对象,返回负整数 ;
  3)如果此对象等于指定对象,返回零 。


2、外部比较器:java.util.Comparator<T> 接口声明了: int compare<T o1, T o2> 方法 
  比较用来排序的两个参数: 
  1)如果o1大于o2,则返回正整数; 
  2)如果o1小于o2,则返回负整数 ;
  3)如果o1等于o2,则返回零 。


这里我们使用TreeSet来举例说明:

1.先定义一个学生类:在学生类实现内部比较器Comparable)接口,我们需要重写int compareTo(T o) 方法。这里我们是对学生成绩排序。double是基本数据类型,这里我们操作的是对象,需要对double进行装箱。

public class Student implements Comparable<Student> {String name;// 姓名int age;// 年龄double score;// 成绩public Student() {}public Student(String name, int age, double score) {super();this.name = name;this.age = age;this.score = score;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";}@Overridepublic int compareTo(Student o) {Double double1 = new Double(this.score);Double double2 = new Double(o.getScore());return double1.compareTo(double2);}}

调用方法;

import java.util.Comparator;import java.util.TreeSet;public class Test01 {public static void main(String[] args) {Student stu1 = new Student("一大大", 20, 88.5);Student stu2 = new Student("二大大", 21, 88);Student stu3 = new Student("三大大", 18, 89);//1.内部比较器  eg:成绩排序TreeSet<Student> treeSet1 = new TreeSet<Student>();treeSet1.add(stu1);treeSet1.add(stu2);treeSet1.add(stu3);showStudent(treeSet1);}public static void showStudent(TreeSet<Student> students) {for (Student student : students) {System.out.println(student);}}}

输出结果:

Student [name=二大大, age=21, score=88.0]
Student [name=一大大, age=20, score=88.5]
Student [name=三大大, age=18, score=89.0]


2.使用外部比较器Comparator)来实现:先定义一个外部比较器的方法来实现接口Comparator,重写 int compare<T o1, T o2> 方法 ,这里我们来比较年龄。

class ageComp implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.age - o2.age;}}
调用方法:

//2.外部比较器 eg:年龄排序Comparator<Student> comparator = new ageComp();TreeSet<Student> treeSet2 = new TreeSet<>(comparator);treeSet2.add(stu1);treeSet2.add(stu2);treeSet2.add(stu3);showStudent(treeSet2);


输出结果:

Student [name=三大大, age=18, score=89.0]
Student [name=一大大, age=20, score=88.5]
Student [name=二大大, age=21, score=88.0]


3.当然,我们还可以用匿名内部类来写Comparator:这里我们来按名字排序。

//3.外部比较器内部类 eg:姓名排序TreeSet<Student> treeSet3 = new TreeSet<>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o1.name.compareTo(o2.name);}});treeSet3.add(stu1);treeSet3.add(stu2);treeSet3.add(stu3);showStudent(treeSet3);
输出结果:

Student [name=一大大, age=20, score=88.5]
Student [name=三大大, age=18, score=89.0]
Student [name=二大大, age=21, score=88.0]


最后,总结一下两种比较器的区别: 
1)如果使用内部比较器,需要比较的对象必须要实现Comparable接口,并重写compareTo( T o)方法,否则不能直接使用Collections中的sort方法,程序会报错。因为程序不知道你要以何种方式来进行比较。 
2)使用外部比较器,需要自己写一个比较器实现Comparator接口,并实现compare(T o1, T o2)方法,根据自己的需求定义比较规则。使用外部比较器这种方式比较灵活。


原创粉丝点击