網(wǎng)站換新的空間域名解析怎么做愛站網(wǎng)長尾關(guān)鍵詞挖掘工具下載
文章目錄
- Comparable與Comparator接口
- Comparable接口
- Comparator接口
Comparable與Comparator接口
我們可能會(huì)遇到這樣的問題:怎么對(duì)一個(gè)對(duì)象數(shù)組進(jìn)行排序? 比如對(duì)一個(gè)狗類對(duì)象數(shù)組進(jìn)行排序,而想到這,我們又會(huì)有一個(gè)問題:怎么比較兩個(gè)對(duì)象?如果我想自定義標(biāo)準(zhǔn),怎么辦?
與基本類型的比較并排序不同,對(duì)象數(shù)組沒有一個(gè)統(tǒng)一的標(biāo)準(zhǔn)來進(jìn)行比較來排序,此時(shí)就可以基于Comparable
接口實(shí)現(xiàn)或者基于比較器實(shí)現(xiàn)(Comparator
接口)
- 自然排序:基于Comparable接口
- 定制排序:基于Comparator接口
本文均以自定義的Person
類為例:
public class Person {private String name;private int age;public Person(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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}}
Comparable接口
使用了Comparable
接口,意味著此類可排序,使用方法是:在想要實(shí)現(xiàn)比較的類中實(shí)現(xiàn)Comparable
接口并重寫compareTo()
方法
我們先觀察一下Comparable
接口的源碼:
我們發(fā)現(xiàn),Comparable
接口中只有一個(gè)CompareTo
方法
觀察完畢后,我們看如下實(shí)現(xiàn)代碼:
//Person.java
//實(shí)現(xiàn)Comparable接口
public class Person implements Comparable<Person> {private String name;private int age;public Person(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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}//重寫compareTo方法,這里按照name(字符串)比較@Overridepublic int compareTo(Person o) {if(this.name.compareTo(o.name) > 0) {return 1;}else if(this.name.compareTo(o.name) < 0) {return -1;}else {return 0;}}
}//Test.java
import java.util.Arrays;public class Test {public static void main(String[] args) {Person[] people = new Person[]{new Person("zhangsan", 23), new Person("lisi", 15),new Person("wangwu", 42)};//實(shí)現(xiàn)了Comparable接口后,可以通過Arrays類中的排序方法給對(duì)象數(shù)組排序了Arrays.sort(people);for(Person p : people) {System.out.println(p);}}
}
打印結(jié)果如下:
-
Comparable
接口后面的<>
是泛型知識(shí),傳入要比較的類即可 -
實(shí)現(xiàn)
Comparable
接口必須重寫CompareTo
方法,方法要求返回int
類型的值,一般內(nèi)部實(shí)現(xiàn)的邏輯:調(diào)用方法的對(duì)象 > 作為參數(shù)的對(duì)象,返回正數(shù);調(diào)用方法的對(duì)象 < 作為參數(shù)的對(duì)象,返回負(fù)數(shù);調(diào)用方法的對(duì)象 == 作為參數(shù)的對(duì)象,返回0
-
一個(gè)類實(shí)現(xiàn)了
Comparable
接口,那么就可以調(diào)用Arrays
類中的sort
方法對(duì)存放此類對(duì)象的數(shù)組進(jìn)行排序 -
一個(gè)實(shí)現(xiàn)了
Comparable
接口的類只能重寫一個(gè)compareTo
方法,這也意味著標(biāo)準(zhǔn)被固定
Comparator接口
前面提到,基于Comparable
接口實(shí)現(xiàn)比較的標(biāo)準(zhǔn)固定,且不便在原代碼修改,這種情況下,我們可以通過Comparator
接口(比較器)實(shí)現(xiàn),方法是:定義一個(gè)或多個(gè)比較器類,實(shí)現(xiàn)Comparator
接口,并重寫Compare
方法
我們先觀察一下Comparator
接口的一部分源碼:
這部分源碼顯示,Comparator
接口中包含compare
和equals
方法,實(shí)現(xiàn)了Comparator
接口的類可以不重寫equals
方法,但是一定要重寫compare
方法
觀察完畢后,我們看如下實(shí)現(xiàn)代碼:
//Person.java
public class Person {private String name;private int age;public Person(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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}}//AgeComparator.java
//以年齡比較的比較器
import java.util.Comparator;public class AgeComparator implements Comparator<Person> {@Overridepublic int compare(Person o1, Person o2) {return o1.getAge() - o2.getAge();}
}//NameComparator.java
//以名字比較的比較器
import java.util.Comparator;public class NameComparator implements Comparator<Person> {@Overridepublic int compare(Person o1, Person o2) {return o1.getName().compareTo(o2.getName());}
}//Test.java
import java.util.Arrays;public class Test {public static void main(String[] args) {Person[] people = new Person[]{new Person("zhangsan", 23), new Person("lisi", 15),new Person("wangwu", 42)};//使用時(shí),必須實(shí)例化比較器對(duì)象AgeComparator ageComparator = new AgeComparator();NameComparator nameComparator = new NameComparator();//正常使用System.out.println(ageComparator.compare(new Person("張三", 16), new Person("李四", 10)));//與Arrays類中的sort方法配合使用Arrays.sort(people, ageComparator);for(Person p : people) {System.out.println(p);}}
}
打印結(jié)果如下:
- 要比較的對(duì)象的類不需要實(shí)現(xiàn)
Comparator
接口,比較器需要實(shí)現(xiàn)Comparator
接口,并在<>
內(nèi)給出要比較的類,并重寫compare
方法 - 重寫的
compare
方法有兩個(gè)參數(shù),分別是要比較的兩個(gè)對(duì)象,重寫的compare
方法要求:返回值的正負(fù)以及零,表示不同的比較結(jié)果。例如,左參數(shù)對(duì)象大于右參數(shù)對(duì)象,返回正值;左參數(shù)對(duì)象小于右參數(shù)對(duì)象,返回負(fù)值;左右參數(shù)對(duì)象相等,返回0 - 使用時(shí),必須實(shí)例化比較器類對(duì)象。可以選擇直接調(diào)用其中的
compare
方法比較單一對(duì)象,也可以配合Arrays
類中的sort
方法對(duì)對(duì)象數(shù)組進(jìn)行排序,此時(shí)sort
方法需要兩個(gè)參數(shù):1. 對(duì)象數(shù)組 2. 比較器對(duì)象 - 比較器可以創(chuàng)建若干個(gè),意味著我們可以定義多個(gè)標(biāo)準(zhǔn),相對(duì)靈活一些
區(qū)別:
Comparable
相當(dāng)于 “內(nèi)部比較器”,Comparator
相當(dāng)于 “外部比較器”- 對(duì)于基于
Comparable
的比較,需要手動(dòng)實(shí)現(xiàn)接口,侵入性比較強(qiáng),但一旦實(shí)現(xiàn),每次調(diào)用該類都有順序,屬于內(nèi)部順序- 對(duì)于基于
Comparator
的比較,需要實(shí)現(xiàn)一個(gè)比較器對(duì)象,對(duì)待比較類的侵入性弱,但對(duì)算法代碼實(shí)現(xiàn)侵入性強(qiáng)
侵入性:讓用戶代碼產(chǎn)生對(duì)框架的依賴,這些代碼不能直接脫離框架使用,不利于代碼的復(fù)用
關(guān)于對(duì)象的比較,數(shù)據(jù)結(jié)構(gòu)部分會(huì)經(jīng)常用到
我們的SE部分的補(bǔ)充知識(shí)到此結(jié)束了,小褲馬上會(huì)發(fā)一篇SE語法合集