参考:https://www.cnblogs.com/igoodful/p/9517784.html
Collections有两种比较规则方式,第一种是使用自身的比较规则:
该类必须实现Comparable接口并重写comparTo方法。
this可以想象为1,传入对象o想象为2,返回1-2即按升序排序。返回2-1即按降序排序。
1、首先编写一个实现Comparable接口的实体类
package com.abc;
//Comparable接口后面一定要加上需要比较的数据类型
public class Person implements Comparable<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 +
'}';
} //自身定义年龄升序
@Override
public int compareTo(Person o) {
return this.age-o.age;
}
}
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,意思是开发者还是要在具体场景下选择最合适的那种比较器而已。