Comparable接口和Comparator接口的用法:
Comparable接口位于 java.lang包下,Comparator接口位于java.util包下。
Comparable: 内部比较器,一个类如果想要使用 Collections.sort(list) 方法进行排序,则需要实现该接口
Comparator: 外部比较器用于对那些没有实现Comparable接口或者对已经实现的Comparable中的排序规则不满意进行排序.无需改变类的结构,更加灵活。
两种比较器Comparable和Comparator,后者相比前者有如下优点:
1、如果实现类没有实现Comparable接口,又想对两个类进行比较(或者实现类实现了Comparable接口,但是对compareTo方法内的比较算法不满意),那么可以实现Comparator接口,自定义一个比较器,写比较算法
2、实现Comparable接口的方式比实现Comparator接口的耦合性 要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不需要对实现类有任何修 改。从这个角度说,其实有些不太好,尤其在我们将实现类的.class文件打成一个.jar文件提供给开发者使用的时候。实际上实现Comparator 接口的方式后面会写到就是一种典型的策略模式。
Comparable:
Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现,compareTo方法也被称为自然比较方法。
1 public class Student implements Comparable<Student>{ 2 private String name; 3 private Integer age; 4 private int stuNo; 5 6 public Student(String name,Integer age,int stuNo){ 7 this.name = name; 8 this.age = age; 9 this.stuNo = stuNo; 10 } 11 public String getName() { 12 return name; 13 } 14 15 public void setName(String name) { 16 this.name = name; 17 } 18 19 public Integer getAge() { 20 return age; 21 } 22 23 public void setAge(Integer age) { 24 this.age = age; 25 } 26 27 public int getStuNo() { 28 return stuNo; 29 } 30 31 public void setStuNo(int stuNo) { 32 this.stuNo = stuNo; 33 } 34 35 //和自己比较 36 @Override 37 public int compareTo(Student o) { 38 return this.stuNo - o.getStuNo(); 39 } 40 }
测试类:
1 public class Test3 { 2 public static void main(String[] args) { 3 Student s1 = new Student("ming",8,1); 4 Student s2 = new Student("tian",9,2); 5 //通过s1 和 s2 的stuNo进行比较 6 System.out.println("s1的stuNo-s2的stuNo:"+s1.compareTo(s2)); 7 } 8 }
测试结果:
实现Comparable接口的类是可以支持和自己比较的,但是其实代码里面Comparable的泛型可以指定为String或者为其他任何任何类型都可以----只要开发者指定了具体的比较算法就行。
1 public class Person { 2 private String name; 3 private Integer age; 4 5 public Person(String name,Integer age){ 6 this.name = name; 7 this.age = age; 8 } 9 public String getName() { 10 return name; 11 } 12 13 public void setName(String name) { 14 this.name = name; 15 } 16 17 public Integer getAge() { 18 return age; 19 } 20 21 public void setAge(Integer age) { 22 this.age = age; 23 } 24 }
泛型为Person类型:
1 public class PersonComparable implements Comparable<Person> { 2 private String name; 3 private int age; 4 5 public PersonComparable(String name, int age){ 6 this.age = age; 7 this.name = name; 8 } 9 10 11 //排序规则,自己实现排序逻辑 12 @Override 13 public int compareTo(Person o) { 14 //使用age进行排序 15 return this.age - o.getAge(); 16 } 17 }
测试类:
1 public class Test1 { 2 public static void main(String[] args) { 3 PersonComparable p1 = new PersonComparable("xiaoming",3); 4 Person p11 = new Person("xiaom",5); 5 PersonComparable p2 = new PersonComparable("xiaoliang",5); 6 Person p22 = new Person("xiaol",4); 7 System.out.println("p1和p11的age比较:"+p1.compareTo(p11)); 8 System.out.println("p2和p22的age比较:"+p2.compareTo(p22)); 9 } 10 }
测试结果:
Comparator:
Comparator可以认为是是一个外比较器,个人认为有两种情况可以使用实现Comparator接口的方式:
1、一个对象不支持自己和自己比较(没有实现Comparable接口),但是又想对两个对象进行比较
2、一个对象实现了Comparable接口,但是开发者认为compareTo方法中的比较方式并不是自己想要的那种比较方式
Comparator接口里面有一个compare方法,方法有两个参数T o1和T o2,是泛型的表示方式,分别表示待比较的两个对象,方法返回值和Comparable接口一样是int.
1 public class PersonComparator implements Comparator<Person> { 2 //排序算法,自己实现排序逻辑 3 @Override 4 public int compare(Person o1, Person o2) { 5 //因为Person对象的age属性使Integer类型的,Integer实现了Comparable接口,实现了compareTo方法 6 return o1.getAge().compareTo(o2.getAge()); 7 } 8 }
测试类:
1 public class Test2 { 2 public static void main(String[] args) { 3 PersonComparator personComparator = new PersonComparator(); 4 Person p1 = new Person("xiaomi",10); 5 Person p2 = new Person("xiaowei",30); 6 // 因为使用的是Integer默认实现,所以 7 // 如果结果>0,表示p1.get>p2.age; 8 // 如果结果=0,表示p1.age = p2.age; 9 // 如果结果<0,表示p1.age < p2.age; 10 System.out.println("p1和p2比较结果:"+personComparator.compare(p1, p2)); 11 } 12 }
测试结果: