相同:
Comparable和Comparator都是用来实现对象的比较、排序
要想对象比较、排序,都需要实现Comparable或Comparator接口
Comparable和Comparator都是Java的接口
不同:
Comparator位于java.util包下,而Comparable位于java.lang包下
Comparable接口的实现是在类的内部(如 String、Integer已经实现了Comparable接口,自己就可以完成比较大小操作),Comparator接口的实现是在类的外部(可以理解为一个是自已完成比较,一个是外部程序实现比较)
实现Comparable接口要重写compareTo方法,实现Comparator需要重写 compare 方法
总结:
如果比较的方法只要用在一个类中,用该类实现Comparable接口就可以
如果比较的方法在很多类中需要用到,就自己写个类实现Comparator接口,这样当要比较的时候把实现了Comparator接口的类传过去就可以,省得重复造轮子。这也是为什么Comparator会在java.util包下的原因。
使用Comparator的优点是:1.与实体类分离 2.方便应对多变的排序规则
1.1实体类User.java
内部排序:comparable
import java.util.Comparator; public class User implements Comparable{ private String name; private int age; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public int getAge() { return age; } public User() { } public User(String name, int age) { this.name = name; this.age = age; } //先年龄再姓名 @Override public int compareTo(Object o) { User temp= (User) o; int i=this.age-temp.getAge(); if (i==0){ return this.name.compareTo(temp.getName()); }else{ return i; } } }
1.2实体类User.java
内部排序:comparator
import java.util.Comparator; public class User implements Comparator<User>{ private String name; private int age; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public int getAge() { return age; } public User() { } public User(String name, int age) { this.name = name; this.age = age; } @Override public int compare(User user1, User user2) { if (user1.getName().equals(user2.getName())) { return user1.getAge() - user2.getAge(); } else { return user1.getName().compareTo(user2.getName()); } } }
2.比较器:实现外部排序 comparator(只适用外部排序2,也可以static方法写在实体类)
import java.util.Comparator; public class UserComparator implements Comparator<User> { //先姓名再年龄 @Override public int compare(User user1, User user2) { if (user1.getName().equals(user2.getName())) { return user1.getAge() - user2.getAge(); } else { return user1.getName().compareTo(user2.getName()); } } }
3.测试类:
import java.util.*; public class Main { public static void main(String[] args) { List<User> list = new ArrayList<>(); UserComparator uc = new UserComparator(); User u1 = new User("manu", 21); User u2 = new User("sas", 20); User u3 = new User("manu", 20); list.add(u1); list.add(u2); list.add(u3); //内部排序 //前面大 > 正数;相等 = 0;前者小 < 负数 System.out.println(u1.compareTo(u2)); System.out.println(uc.compare(u1, u2)); Collections.sort(list); System.out.println("comparable:"); for (User user : list) { System.out.println(user.getName() + ":" + user.getAge()); } //外部排序1 Collections.sort(list, new Comparator<User>() { @Override public int compare(User user1, User user2) { if (user1.getName().equals(user2.getName())) { return user1.getAge() - user2.getAge(); } else { return user1.getName().compareTo(user2.getName()); } } }); //外部排序2 Collections.sort(list, uc); //外部排序3 Collections.sort(list,new User()); System.out.println("comparator:"); for (User user : list) { System.out.println(user.getName() + ":" + user.getAge()); } } }
测试结果:
comparable:
manu:20
sas:20
manu:21
comparator:
manu:20
manu:21
sas:20
备注:
JDK8也可用Lambda表达式写