Comparable是排序接口: 若一个类实现了Comparable接口,就意味着“该类支持排序”。
Comparator是比较器: 我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。
我们需要创建一个包含了用户列表的 List 集合,并按用户的年龄从大到小进行排序,具体实现代码如下: 第一种:实现Comparable<>接口
写一个Person类:
- class Person implements Comparable<Person>{
-
- Integer id;
- String name;
- Integer age;
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public Integer getAge() {
- return age;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
- @Override
- public String toString() {
- return "Person{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", age=" + age +
- '}';
- }
- @Override
- public int compareTo(Person o) {
- //按照年龄从大到小排序
- return o.getAge()-this.getAge();
- }
- }
实现结果测试:
- public static void main(String[] args){
- //假设放进去三个对象,直接调用
- List<Person> pr=new ArrayList<Person>(){{
- add(new Person(1,"huitao1",32));
- add(new Person(2,"huitao2",40));
- add(new Person(3,"huitao3",28));
- }};
- //很重要
- Collections.sort(pr);
- pr.forEach(p->{
- System.out.print(p);
- });
- }

结果按照40、32、28进行了排序
第二种: Comparator 排序
Comparable 是类内部的比较方法,而 Comparator 是排序类外部的比较器。使用 Comparator 比较器,无需修改原 Person 类,只需要扩充一个 Person 类的比较器就行了,Comparator 的实现方法有以下两种:
- 新建 Comparator 比较器;
- 使用 Comparator 匿名类比较器。
- static class Person {
-
- Integer id;
- String name;
- Integer age;
-
- public Person(Integer id, String name, Integer age) {
- this.id = id;
- this.name = name;
- this.age = age;
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public Integer getAge() {
- return age;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
- @Override
- public String toString() {
- return "Person{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", age=" + age +
- '}';
- }
- }
编写一个比较器类:
- static class ToPerson implements Comparator<Person>{
-
- @Override
- public int compare(Person o1, Person o2) {
- return o1.getAge() - o2.getAge();
- }
- }
- public static void main(String[] args){
-
-
-
- List<Person> pr=new ArrayList<Person>(){{
- add(new Person(1,"huitao1",32));
- add(new Person(2,"huitao2",40));
- add(new Person(3,"huitao3",28));
- }};
- //很重要
- Collections.sort(pr,new ToPerson());
- pr.forEach(p->{
- System.out.print(p);
- });
- }
测试结果:

分别为28、32、40,如果要从大到小,可以编写为
static class ToPerson implements Comparator{ @Override public int compare(Person o1, Person o2) { return o2.getAge() - o1.getAge(); } }
以匿名类的方式访问:
- static class Person {
-
- Integer id;
- String name;
- Integer age;
-
- public Person(Integer id, String name, Integer age) {
- this.id = id;
- this.name = name;
- this.age = age;
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public Integer getAge() {
- return age;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
- @Override
- public String toString() {
- return "Person{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", age=" + age +
- '}';
- }
- }
- public static void main(String[] args){
-
-
-
- List<Person> pr=new ArrayList<Person>(){{
- add(new Person(1,"huitao1",32));
- add(new Person(2,"huitao2",40));
- add(new Person(3,"huitao3",28));
- }};
- //很重要
- Collections.sort(pr, new Comparator<Person>() {
- @Override
- public int compare(Person o1, Person o2) {
- return o2.getAge() - o1.getAge();
- }
- });
- pr.forEach(p->{
- System.out.print(p);
- });
- }

第三种:使用 Stream 流排序
- public static void main(String[] args){
-
-
-
- List<Person> pr=new ArrayList<Person>(){{
- add(new Person(1,"huitao1",32));
- add(new Person(2,"huitao2",40));
- add(new Person(3,"huitao3",28));
-
- }};
- pr= pr.stream().sorted(Comparator.comparing(Person::getAge).reversed()).collect(Collectors.toList());
- pr.forEach(p->{
- System.out.print(p);
- });
- }
- static class Person {
-
- Integer id;
- String name;
- Integer age;
-
- public Person(Integer id, String name, Integer age) {
- this.id = id;
- this.name = name;
- this.age = age;
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public Integer getAge() {
- return age;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
- @Override
- public String toString() {
- return "Person{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", age=" + age +
- '}';
- }
- }

stream()如果排序属性出现null,报告空指针个错误,解决办法
- public static void main(String[] args){
-
-
-
- List<Person> pr=new ArrayList<Person>(){{
- add(new Person(1,"huitao1",32));
- add(new Person(2,"huitao2",40));
- add(new Person(3,"huitao3",28));
- add(new Person(4,"huitao3",null));
-
- }};
- pr= pr.stream().sorted(Comparator.comparing(Person::getAge,Comparator.nullsFirst(Integer::compareTo)).reversed()).collect(Collectors.toList());
- pr.forEach(p->{
- System.out.print(p);
- });
- }
- static class Person {
-
- Integer id;
- String name;
- Integer age;
-
- public Person(Integer id, String name, Integer age) {
- this.id = id;
- this.name = name;
- this.age = age;
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public Integer getAge() {
- return age;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
- @Override
- public String toString() {
- return "Person{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", age=" + age +
- '}';
- }
- }

Comparator.nullsFirst 表示将排序字段中的 null 值放到集合最前面,如果想要将 null 值放到集合最后面可以使用 Comparator.nullsLast。