一.比较器的概念
--所谓的比较器指的就是进行大小关系的确定判断,比较器存在的意义:
如果要进行数组的操作,肯定使用java.util.Arrays的操作类来完成,这个类里面提供有绝大部分的数组操作支持,同时在这个类里面还提供有对象数组的排序支持:
static void sort(Object[] a) 对指定对象升序排列的阵列,根据natural ordering的元素。
1 public class MyComparator { 2 public static void main(String[] args) { 3 Integer[] data = new Integer[]{ 4 10, 9, 5, 2, 20 5 }; 6 Arrays.sort(data); //进行对象数组的排序输出 7 System.out.println(Arrays.toString(data)); 8 } 9 }
--运行结果
[2, 5, 9, 10, 20] Process finished with exit code 0
--同样,如果是一个String类型的对象数组,也是可以进行排序输出的:
1 public class MyComparator { 2 public static void main(String[] args) { 3 String[] data = new String[]{ 4 "X", "B", "A", "E", "G" 5 }; 6 Arrays.sort(data); 7 System.out.println(Arrays.toString(data)); 8 } 9 }
--运行结果
[A, B, E, G, X] Process finished with exit code 0
--我们知道java.lang.Integer类与java.lang.String类都是由系统提供的程序类,现在如果有一个自定义的类需要进行排序处理呢?
1 package 常用类库.比较器; 2 3 import java.util.Arrays; 4 5 /** 6 * @author : S K Y 7 * @version :0.0.1 8 */ 9 class Person { 10 private String name; 11 private int age; 12 13 public Person(String name, int age) { 14 this.name = name; 15 this.age = age; 16 } 17 18 @Override 19 public String toString() { 20 return "Person{" + 21 "name='" + name + '\'' + 22 ", age=" + age + 23 '}'; 24 } 25 } 26 27 public class MyComparator { 28 public static void main(String[] args) { 29 Person[] people = new Person[]{ 30 new Person("小强", 80), new Person("老王", 50), new Person("老李", 60) 31 , new Person("小刚", 30) 32 }; 33 Arrays.sort(people); 34 System.out.println(people); 35 } 36 }
--运行结果
Exception in thread "main" java.lang.ClassCastException: 常用类库.比较器.Person cannot be cast to java.lang.Comparable at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320) at java.util.ComparableTimSort.sort(ComparableTimSort.java:188) at java.util.Arrays.sort(Arrays.java:1246) at 常用类库.比较器.MyComparator.main(MyComparator.java:33) Process finished with exit code 1
--可以发现任意一个类,在默认情况下是无法使用系统内部的类实现数字排序和比较需求的,不同的两个Person对象需要占用两个不同的堆内存空间,去比较两个堆堆内存的大小时没有意义的,因此我们需要明确的指定出比较规则.java中为了统一比较规则的定义,提供了比较器Comparable接口,想要实现对象之间的比较,就需要实现Comparable接口
二.Comparable比较器
--通过分析可以发现如果要实现对象的比较肯定需要有比较器来制定比较规则,而比较的规则对于Comparable而言,我们需要知道其基本的定义规则
--范例:实现自定义对象数组排序操作
1 class Person implements Comparable<Person> { 2 private String name; 3 private int age; 4 5 public Person(String name, int age) { 6 this.name = name; 7 this.age = age; 8 } 9 10 /** 11 * 实现Person对象的比较处理 12 * 13 * @param o 要比较的对象 14 * @return 当前数据比传入的对象小返回负数, 否则返回正数, 如果相等则返回0 15 */ 16 @Override 17 public int compareTo(Person o) { 18 return this.age - o.age; 19 } 20 21 @Override 22 public String toString() { 23 return "Person{" + 24 "name='" + name + '\'' + 25 ", age=" + age + 26 '}'; 27 } 28 } 29 30 public class MyComparator { 31 public static void main(String[] args) { 32 Person[] people = new Person[]{ 33 new Person("小强", 80), new Person("老王", 50), new Person("老李", 60) 34 , new Person("小刚", 30) 35 }; 36 Arrays.sort(people); 37 System.out.println(Arrays.toString(people)); 38 } 39 }
--运行结果
[Person{name='小刚', age=30}, Person{name='老王', age=50}, Person{name='老李', age=60}, Person{name='小强', age=80}] Process finished with exit code 0
--因此我们可以通过实现Comparable接口,利用compareTo()方法进行排序规则的定义,而后整个java系统里面就可以为其实现排序处理了
三.Comparator比较器
--Comparator属于一种挽救的比较器支持,其主要的目的是解决一些没有使用Comparable排序的类的对象的排序操作
--例如此时程序项目已经开发完成,并且由于先期的设计并没有考虑到所谓的比较器功能,经过了若干版本的迭代更新之后发现需要对Person类进行排序处理,但是又不能够去修改Person类(无法实现Comparable接口),这时需要一种挽救的形式来进行排序的比较,在Arrays中还存在另一种基于Comparator的排序处理:
static <T> void sort(T[] a, Comparator<? super T> c) 根据指定的比较器引发的顺序对指定的对象数组进行排序.在java.util.Comparator里面最初只定义有一个排序的compare()方法 int compare(T o1, T o2) 比较其两个参数的顺序,但是后来持续发展,在JDK1.8之后有增加了许多static的方法.
--范例,定义排序规则类
1 class Person { 2 private String name; 3 private int age; 4 5 public Person(String name, int age) { 6 this.name = name; 7 this.age = age; 8 } 9 10 public String getName() { 11 return name; 12 } 13 14 public void setName(String name) { 15 this.name = name; 16 } 17 18 public int getAge() { 19 return age; 20 } 21 22 public void setAge(int age) { 23 this.age = age; 24 } 25 26 @Override 27 public String toString() { 28 return "Person{" + 29 "name='" + name + '\'' + 30 ", age=" + age + 31 '}'; 32 } 33 } 34 class PersonComparator implements Comparator<Person>{ 35 @Override 36 public int compare(Person o1, Person o2) { 37 return o1.getAge() - o2.getAge(); 38 } 39 } 40 41 public class MyComparator { 42 public static void main(String[] args) { 43 Person[] people = new Person[]{ 44 new Person("小强", 80), new Person("老王", 50), new Person("老李", 60) 45 , new Person("小刚", 30) 46 }; 47 Arrays.sort(people,new PersonComparator()); 48 System.out.println(Arrays.toString(people)); 49 } 50 }
--对于排序的定义,如果不是必须的情况下,不建议使用Comparator,最好以实现Comparable为首页选择
--总结:解释Comparable和Comparator的区别:
java.lang.Comparable是在类定义的时候实现的父接口,主要用于定义排序规则,直面只有一个CompareTo()的方法;java.util.Comparator是挽救的比较器操作,需要设置单独的比较器实现类来完成,提供有compare()方法