Comparable和Comparator都是用來實作集合中元素的比較、排序的。
Comparable是在集合内部定義的方法實作的排序,而Comparator是在集合外部實作的排序,如果想實作排序,就需要在集合外定義Comparator接口的方法或在集合内實作Comparable接口的方法。
這裡用一個年齡和姓名相同時自動覆寫之前的記錄的例子來講下Comparable和Comparator的使用:
先看下Comparable:
/**
* Student
*
* @author yuzhentao
*/
public class Student implements Comparable<Student> {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Student)) {
throw new ClassCastException("不是學生對象");
}
Student s = (Student) o;
return this.name.equals(s.name) && this.age == s.age;
}
@Override
public int compareTo(@NonNull Student another) {
/**
* compareTo():大于0表示前一個資料比後一個資料大, 0表示相等,小于0表示前一個資料小于後一個資料
* 相等時會走到equals(),這裡講姓名年齡都一樣的對象當作一個對象
*/
int num = Integer.valueOf(this.age).compareTo(another.age);//先比較年齡
if (num == 0) {
return this.name.compareTo(another.name);//如果年齡相同,再比較姓名(姓名按Unicode編碼升序排序)
}
return num;
}
}
先寫個學生類實作Comparable接口,重寫compareTo()方法,這裡按照年齡升序排列,并實作hashCode()和equals(),這兩個方法要用來比較當年齡和姓名都相同時的處理。都相同時覆寫之前的一條記錄。還要實作toString(),最後列印的Student對象就是以toString()的格式列印出來。
compareTo()傳回值大于0表示前一個資料比後一個資料大, 0表示相等,小于0表示前一個資料小于後二個資料,相等時會走到equals(),這裡将姓名年齡都一樣的對象當作一個對象。
然後是主界面:
/**
* 主界面
*
* @author yuzhentao
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
}
private void initData() {
TreeMap<Student, String> map = new TreeMap<>();
map.put(new Student("a", 28), "北京");
map.put(new Student("b", 23), "上海");
map.put(new Student("c", 22), "南京");
map.put(new Student("c", 22), "深圳");//此Key與上面的相同,會将上面的Value覆寫
map.put(new Student("d", 25), "杭州");
map.put(new Student("d", 25), "廣州");//此Key與上面的相同,會将上面的Value覆寫
Set<Map.Entry<Student, String>> set = map.entrySet();
Iterator<Map.Entry<Student, String>> iterator = set.iterator();
while (iterator.hasNext()) {
Map.Entry<Student, String> entry = iterator.next();
Student student = entry.getKey();
String address = entry.getValue();
Log.e("yuzhentao", "Student=" + student + " Address=" + address);
}
}
}
這裡使用一個TreeMap來存儲鍵值對,然後使用Iterator來取出集合裡面的鍵值,使用TreeMap可以排序,至于規則就是比較器裡定義的規則了。
然後看下結果:
03-30 13:54:53.155 10419-10419/? E/yuzhentao: Student=Student{name='c', age=22} Address=深圳
03-30 13:54:53.155 10419-10419/? E/yuzhentao: Student=Student{name='b', age=23} Address=上海
03-30 13:54:53.155 10419-10419/? E/yuzhentao: Student=Student{name='d', age=25} Address=廣州
03-30 13:54:53.155 10419-10419/? E/yuzhentao: Student=Student{name='a', age=28} Address=北京
再看下Comparator:
Comparator使用和Comparable差不多,就是形式上有點不一樣,也是先寫個學生類,不過不用繼承,但是其他方法要寫好
/**
* Student
*
* @author yuzhentao
*/
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Student)) {
throw new ClassCastException("不是學生對象");
}
Student s = (Student) o;
return this.name.equals(s.name) && this.age == s.age;
}
}
然後是實作Comparator,這裡要使用get方法來得到值
/**
* StudentComparator
*
* @author yuzhentao
*/
public class StudentComparator implements Comparator<Student> {
@Override
public int compare(Student lhs, Student rhs) {
/**
* compareTo():大于0表示前一個資料比後一個資料大, 0表示相等,小于0表示前一個資料小于後一個資料
* 相等時會走到equals(),這裡講姓名年齡都一樣的對象當作一個對象
*/
int num = Integer.valueOf(lhs.getAge()).compareTo(rhs.getAge());//先比較年齡
if (num == 0) {
return lhs.getName().compareTo(rhs.getName());//如果年齡相同,再比較姓名(姓名按Unicode編碼升序排序)
}
return num;
}
}
最後是主界面,這裡還是使用TreeMap,因為可以傳入Comparator
/**
* 主界面
*
* @author yuzhentao
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
}
private void initData() {
TreeMap<Student, String> map = new TreeMap<>(new StudentComparator());
map.put(new Student("a", 28), "北京");
map.put(new Student("b", 23), "上海");
map.put(new Student("c", 22), "南京");
map.put(new Student("c", 22), "深圳");//此Key與上面的相同,會将上面的Value覆寫
map.put(new Student("d", 25), "杭州");
map.put(new Student("d", 25), "廣州");//此Key與上面的相同,會将上面的Value覆寫
Set<Map.Entry<Student, String>> set = map.entrySet();
Iterator<Map.Entry<Student, String>> iterator = set.iterator();
while (iterator.hasNext()) {
Map.Entry<Student, String> entry = iterator.next();
Student student = entry.getKey();
String address = entry.getValue();
Log.e("yuzhentao", "Student=" + student + " Address=" + address);
}
}
}
看下結果:
03-30 14:01:17.374 22341-22341/? E/yuzhentao: Student=Student{name='c', age=22} Address=深圳
03-30 14:01:17.374 22341-22341/? E/yuzhentao: Student=Student{name='b', age=23} Address=上海
03-30 14:01:17.374 22341-22341/? E/yuzhentao: Student=Student{name='d', age=25} Address=廣州
03-30 14:01:17.374 22341-22341/? E/yuzhentao: Student=Student{name='a', age=28} Address=北京
希望對各位有所幫助。
Demo位址:http://download.csdn.net/detail/qq_23940659/9476637
Demo位址:http://download.csdn.net/detail/qq_23940659/9476698