参考:https://www.cnblogs.com/igoodful/p/9517784.html
Collections有两种比较规则方式,第一种是使用自身的比较规则:
该类必须实现Comparable接口并重写comparTo方法。
this可以想象为1,传入对象o想象为2,返回1-2即按升序排序。返回2-1即按降序排序。
1、首先编写一个实现Comparable接口的实体类
1 package com.abc;
2 //Comparable接口后面一定要加上需要比较的数据类型
3 public class Person implements Comparable<Person>{
4
5 private String name;
6 private int age;
7 private int salary;
8
9 public Person() {
10 }
11
12 public Person(String name, int age, int salary) {
13 this.name = name;
14 this.age = age;
15 this.salary = salary;
16 }
17
18 public String getName() {
19 return name;
20 }
21
22 public void setName(String name) {
23 this.name = name;
24 }
25
26 public int getAge() {
27 return age;
28 }
29
30 public void setAge(int age) {
31 this.age = age;
32 }
33
34 public int getSalary() {
35 return salary;
36 }
37
38 public void setSalary(int salary) {
39 this.salary = salary;
40 }
41
42 @Override
43 public String toString() {
44 return "Person{" +
45 "name='" + name + '\'' +
46 ", age=" + age +
47 ", salary=" + salary +
48 '}';
49 }
50
51 //自身定义年龄升序
52 @Override
53 public int compareTo(Person o) {
54 return this.age-o.age;
55 }
56 }
2、编写测试代码
package com.abc;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PersonTest {
public static void main(String[] args){
List<Person> people = new ArrayList<>();
people.add(new Person("AAA",20,100));
people.add(new Person("BBB",18,109));
people.add(new Person("CCC",30,58));
System.out.println(people);
Collections.sort(people);
System.out.println(people);
}
}
3、运行结果
[Person{name='AAA', age=20, salary=100}, Person{name='BBB', age=18, salary=109}, Person{name='CCC', age=30, salary=58}]
//完成了年龄的升序排列 [Person{name='BBB', age=18, salary=109}, Person{name='AAA', age=20, salary=100}, Person{name='CCC', age=30, salary=58}]
第二个参数为比较器,可以使用它来定义针对集合排序时的比较元素大小的规则。
使用这种方式时,sort方法不要求集合元素必须实现Comparable接口了,因为不会使用元素自身的比较规则。
1、编写一个普通的实体类,不需要实现任何接口
package com.abcd;
public class Person{
private String name;
private int age;
private int salary;
public Person() {
}
public Person(String name, int age, int salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
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 int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
'}';
}
}
2、编写测试代码
package com.abcd; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class PersonTest { public static void main(String[] args){ List<Person> people = new ArrayList<>(); people.add(new Person("AAA",20,100)); people.add(new Person("BBB",18,109)); people.add(new Person("CCC",30,58)); System.out.println(people);
//排序规则 salary降序 Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { return o2.getSalary()- o1.getSalary(); } }); System.out.println(people); } }
3、运行结果
[Person{name='AAA', age=20, salary=100}, Person{name='BBB', age=18, salary=109}, Person{name='CCC', age=30, salary=58}] [Person{name='BBB', age=18, salary=109}, Person{name='AAA', age=20, salary=100}, Person{name='CCC', age=30, salary=58}]
总结
总结一下,两种比较器Comparable和Comparator,后者相比前者有如下优点:
1、如果实现类没有实现Comparable接口,又想对两个类进行比较(或者实现类实现了Comparable接口,但是对compareTo方法内的比较算法不满意),那么可以实现Comparator接口,自定义一个比较器,写比较算法
2、实现Comparable接口的方式比实现Comparator接口的耦合性 要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不需要对实现类有任何修 改。从这个角度说,其实有些不太好,尤其在我们将实现类的.class文件打成一个.jar文件提供给开发者使用的时候。实际上实现Comparator 接口的方式后面会写到就是一种典型的策略模式。
当然,这不是鼓励用Comparator,意思是开发者还是要在具体场景下选择最合适的那种比较器而已。