相同:
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表達式寫