Java中Comparable接口和Comparator接口的使用比較
在Java中,我們會經(jīng)常使用到自定義類,那我們?nèi)绾芜M(jìn)行自定義類的比較呢?
1.Comparable接口
普通數(shù)據(jù)的比較
int a=10;
int b=91;
System.out.println(a<b);那自定義類型可不可以這樣比較呢?看一下代碼

我們發(fā)現(xiàn)會報錯,因?yàn)樽远x類型,stu1和stu2里面存的是引用,是無法直接根據(jù)姓名或年齡進(jìn)行比較的。
1.1Comparable接口的使用
如果想要自定義類型根據(jù)年齡和名字進(jìn)行比較,這時候就要用到我們的Comparable接口。

當(dāng)我們觀察Comparable接口的底層細(xì)節(jié)會發(fā)現(xiàn)有一個<T>和一個方法,<T>代表我們要比較的類型,方法是我們根據(jù)實(shí)際情況來重寫compareTo方法,也就是比較的規(guī)則。
1.根據(jù)年齡比較
自定義類中具體實(shí)現(xiàn)
class Student implements Comparable<Student>{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student o) {
//根據(jù)年齡比較
/*if(this.age>o.age){
return 1;
}else if (this.age==o.age){
return 0;
}else {
return -1;
}*/
return this.age-o.age;
}
}完整代碼
class Student implements Comparable<Student>{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student o) {
//根據(jù)年齡比較
/*if(this.age>o.age){
return 1;
}else if (this.age==o.age){
return 0;
}else {
return -1;
}*/
return this.age-o.age;
}
}
public class Test {
public static void main(String[] args) {
Student stu1=new Student("zhansan",18);
Student stu2=new Student("man",24);
System.out.println(stu1.compareTo(stu2));
}
}
2.根據(jù)名字比較
class Student implements Comparable<Student>{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student o) {
return this.name.compareTo(o.name);
}
}
public class Test {
public static void main(String[] args) {
Student stu1=new Student("zhansan",18);
Student stu2=new Student("man",24);
System.out.println(stu1.compareTo(stu2));
}
}
由于名字是String類,String類在底層中也實(shí)現(xiàn)了compareTo方法,所以我們可以直接調(diào)用compareTo方法來實(shí)現(xiàn)名字的比較。
3. 多個對象之間的比較
多個對象我們可以用一個對應(yīng)類的數(shù)組來存儲,然后思路就是讓數(shù)組里面的元素就行比較。
這里模擬了冒泡排序進(jìn)行比較。
根據(jù)名字來排序
import java.util.Arrays;
class Student implements Comparable<Student>{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
return this.name.compareTo(o.name);
}
}
public class Test {
public static void mysort(Comparable[] comparables){
for (int i = 0; i < comparables.length-1; i++) {
for(int j=0;j<comparables.length-1-i;j++){
if(comparables[j].compareTo(comparables[j+1])>0){
Comparable tmp=comparables[j];
comparables[j]=comparables[j+1];
comparables[j+1]=tmp;
}
}
}
}
public static void main(String[] args) {
Student[] students=new Student[]{
new Student("zhansan",18),
new Student("man",24),
new Student("lebron",23)
};
mysort(students);
System.out.println(Arrays.toString(students));
}
}

根據(jù)年齡來排序
import java.util.Arrays;
class Student implements Comparable<Student>{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
return this.age-o.age;
}
}
public class Test {
public static void mysort(Comparable[] comparables){
for (int i = 0; i < comparables.length-1; i++) {
for(int j=0;j<comparables.length-1-i;j++){
if(comparables[j].compareTo(comparables[j+1])>0){
Comparable tmp=comparables[j];
comparables[j]=comparables[j+1];
comparables[j+1]=tmp;
}
}
}
}
public static void main(String[] args) {
Student[] students=new Student[]{
new Student("zhansan",18),
new Student("man",24),
new Student("lebron",23)
};
mysort(students);
System.out.println(Arrays.toString(students));
}
}

4.總結(jié)
1.當(dāng)前階段如果我們想要進(jìn)行自定義類型之間的比較,我們要使用Comparable接口。
2.重寫接口里面的方法是我們根據(jù)需求來決定如何重寫compareTo方法,重寫后的compareTo方法里面的具體實(shí)現(xiàn)就是我們的比較規(guī)則。
2.Comparator接口
我們發(fā)現(xiàn)當(dāng)我們使用Comparable接口時并不是那么靈活,因?yàn)樗鼘?shí)現(xiàn)的比較規(guī)則是寫死的,如果我們想要換一種比較規(guī)則,我們必須要對實(shí)現(xiàn)對比較方法里面的重新構(gòu)造。
那有沒有比較靈活的比較方式呢?答案就是Comparator接口。
AgeComparator類
public class AgeComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age- o2.age;
}
}
NameComparator類
public class NameComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.name.compareTo(o2.name);
}
}
主函數(shù)部分
根據(jù)年齡排序
public class Test {
public static void main(String[] args) {
Student[] students=new Student[]{
new Student("zhansan",18),
new Student("man",24),
new Student("lebron",23)
};
NameComparator nameComparator=new NameComparator();
AgeComparator ageComparator=new AgeComparator();
Arrays.sort(students,ageComparator);
System.out.println(Arrays.toString(students));
}
}

根據(jù)名字比較
public class Test {
public static void main(String[] args) {
Student[] students=new Student[]{
new Student("zhansan",18),
new Student("man",24),
new Student("lebron",23)
};
NameComparator nameComparator=new NameComparator();
AgeComparator ageComparator=new AgeComparator();
Arrays.sort(students,nameComparator);
System.out.println(Arrays.toString(students));
}
}

這里我們定義了AgeComparator類和NameComparator類,它們都使用了Comparator這個接口,
然后在自己的類里面重寫了compareTo方法。
根據(jù)以上類實(shí)現(xiàn)的對象可以認(rèn)為是比較規(guī)則,將這些對象作為sort函數(shù)的參數(shù),就可以靈活實(shí)現(xiàn)不同比較方式的轉(zhuǎn)變。
相對于Comparable接口來說,Comparator不需要改變函數(shù)內(nèi)部的具體實(shí)現(xiàn)來改變比較規(guī)則,只需改變函數(shù)的參數(shù)就行了,這樣更安全也更方便。
總結(jié)
到此這篇關(guān)于Java中Comparable接口和Comparator接口使用的文章就介紹到這了,更多相關(guān)Java Comparable和Comparator接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
把spring boot項(xiàng)目發(fā)布tomcat容器(包含發(fā)布到tomcat6的方法)
這篇文章主要介紹了把spring boot項(xiàng)目發(fā)布tomcat容器(包含發(fā)布到tomcat6的方法),然后在文章給大家提到了如何將Spring Boot項(xiàng)目打包部署到外部Tomcat,需要的朋友參考下吧2017-11-11
MyBatis-Plus實(shí)現(xiàn)條件查詢的三種格式例舉詳解
本文主要介紹了MyBatis-Plus三中條件查詢格式的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
SpringBoot中定時任務(wù)@Scheduled注解的使用解讀
這篇文章主要介紹了SpringBoot中定時任務(wù)@Scheduled注解的使用解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09
使用Spring事件機(jī)制實(shí)現(xiàn)異步的方法
這篇文章主要介紹了使用Spring事件機(jī)制實(shí)現(xiàn)異步的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06
spring?boot如何配置靜態(tài)路徑詳解(404出現(xiàn)的坑)
這篇文章主要給大家介紹了關(guān)于spring?boot如何配置靜態(tài)路徑的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2022-02-02

