Comparable接口:让自定义的对象具有比较规则
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; /* * Comparable接口:让自定义的对象具有比较规则 * * */ public class ComparableDemo { public static void main(String[] args) { ArrayList<Student> list = new ArrayList<Student>(); list.add(new Student("zhangsan", 18)); list.add(new Student("zhangsan", 28)); list.add(new Student("lisi", 20)); list.add(new Student("wangwu", 20)); list.add(new Student("xiaoming", 21)); list.add(new Student("dahuang", 22)); // 列表中的所有元素都必须实现 Comparable 接口 Collections.sort(list, new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { // o1和o2比较:升序 // 以姓名为主进行升序,如果姓名相等再以年龄为主进行升序 // return o1.getName().equals(o2.getName()) ? o1.getAge() - // o2.getAge() // : o1.getName().compareTo(o2.getName()); // o2和o1比较:降序 // 以年龄为主进行降序,如果年龄相等再以姓名为主进行降序 return o2.getAge() == o1.getAge() ? o2.getName().compareTo(o1.getName()) : o2.getAge() - o1.getAge(); } });// 我使用Comparator让Student具有比较规则 for (Student s : list) { System.out.println(s); } } }
package cn.edu360; public class Person { private String name; private int age; private char sex; public Person() { super(); } public Person(String name, int age, char sex) { this.name = name; this.age = age; this.sex = sex; } 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 char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]"; } }
输出结果:
Student [name=zhangsan, age=28]
Student [name=dahuang, age=22]
Student [name=xiaoming, age=21]
Student [name=wangwu, age=20]
Student [name=lisi, age=20]
Student [name=zhangsan, age=18]
Comparator比较接口:
覆盖元素对象已有的比较规则
让没有比较规则的对象具有比较规则
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; /* * Comparator比较接口: * 覆盖元素对象已有的比较规则 * 让没有比较规则的对象具有比较规则 * * */ public class ComparatorDemo { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); list.add(10); list.add(0); list.add(20); list.add(-19); list.add(19); list.add(100); System.out.println(list);// [10, 0, 20, -19, 19, 100] // 匿名内部类本质上一个继承了类或者实现接口的匿名子类对象 Comparator c = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { // o1和o2比较:升序 // return o1.compareTo(o2); // return o1-o2;//对于整数类型的值来说,使用compareTo方法和直接用减法的效果是一样的 // o2和o1比较:降序 // return o2.compareTo(o1); return o2 - o1;// 对于整数类型的值来说,使用compareTo方法和直接用减法的效果是一样的 } }; // public static <T> void sort(List<T> list, Comparator<? super T> c) // 根据指定比较器产生的顺序对指定列表进行排序 Collections.sort(list, c); System.out.println(list);// [100, 20, 19, 10, 0, -19] int location = Collections.binarySearch(list, 0, c);// 想对集合进行降序二分查找的时候,需要用到比较器 System.out.println(location); } }
输出结果:
[10, 0, 20, -19, 19, 100]
[100, 20, 19, 10, 0, -19]
4
总结:
Comparable和Comparator都是用来实现集合中元素的比较、排序的。
Comparable是在集合内部定义的方法实现的排序,位于java.util下。
Comparator是在集合外部实现的排序,位于java.lang下。
Comparable是一个对象本身就已经支持自比较所需要实现的接口,如String、Integer自己就实现了Comparable接口,可完成比较大小操作。自定义类要在加入list容器中后能够排序,也可以实现Comparable接口,在用Collections类的sort方法排序时若不指定Comparator,那就以自然顺序排序。所谓自然顺序就是实现Comparable接口设定的排序方式。
Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足要求时,可写一个比较器来完成两个对象之间大小的比较。Comparator体现了一种策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。
总而言之Comparable是自已完成比较,Comparator是外部程序实现比较。