Java的Comparable,Comparator和Cloneable三大接口詳解
1、比較器
①比較器的引入
a.首先,當(dāng)我們單一地比較某一種數(shù)據(jù)類型的數(shù)組時(shí),可以直接用Arrays.sort()進(jìn)行實(shí)現(xiàn)
b.而當(dāng)我們同時(shí)含有多個(gè)參數(shù)時(shí),并沒有告訴我們按照什么來進(jìn)行排序,此時(shí),若是用Arrays.sort()就會(huì)出現(xiàn)報(bào)錯(cuò)的情況
基于這種情況,我們了解到,若是要將自定義類型進(jìn)行大小比較 ,就要引入能夠?qū)崿F(xiàn)比較的接口,下面我們介紹Comparable和Comparator這兩種比較器
1.1Comparable接口
①實(shí)現(xiàn)Comparable接口的操作
②通過Comparable接口實(shí)現(xiàn)年齡的排序
③通過Comparable來實(shí)現(xiàn)名字的排序(注意名字是引用類,比較時(shí)應(yīng)該是用compareTo()來進(jìn)行)
④升序降序
由于最終是利用的Arrays.sort()進(jìn)行的比較,該方法底層是升序的操作,若是想轉(zhuǎn)換為降序,只需要將重寫的compareTo()方法中兩項(xiàng)互換位置即可
變?yōu)榻敌蚝蟠a運(yùn)行結(jié)果:
⑤缺點(diǎn)?。?!
Comparable對(duì)類的傾入性很強(qiáng)。由上面我們可知,要想比較新的類型就要更改compareTo()中的類型重新進(jìn)行比較,這個(gè)在以后的工作中極大可能會(huì)使整個(gè)代碼出現(xiàn)邏輯問題,可讀性問題,因此我們引入下一類很靈活,傾入性不強(qiáng)的Comparator接口
⑥整體代碼如下:
import java.util.Arrays; class Student implements Comparable<Student> { public int age; public String name; public double score; public Student(int age,String name,double score){ this.age=age; this.name=name; this.score=score; } @Override public String toString() { return "Student{" + "age=" + age + ", name='" + name + '\'' + ", score=" + score + '}'; } public static void main3(String[] args) { Student student1=new Student(12,"張三",98.0); Student student2=new Student(18,"李四",97.9); //if(student1.compareTo(student2)>0)返回1;根據(jù)下面的方法進(jìn)行進(jìn)一步的返回 System.out.println(student1.compareTo(student2)); } public static void main(String[] args) { Student []student=new Student[3]; student[0]=new Student(36,"zhangsan",98.0); student[1]=new Student(18,"lisi",97.9); student[2]=new Student(27,"wangwu",65.3); System.out.println(Arrays.toString(student)); Arrays.sort(student); System.out.println(Arrays.toString(student)); } public static void main1(String[] args) { int []array=new int []{2,5,3,6,8}; System.out.println(Arrays.toString(array)); Arrays.sort(array); System.out.println(Arrays.toString(array)); } @Override //誰調(diào)用這個(gè)方法,誰就是this public int compareTo(Student o) { //return this.age-o.age; return o.name.compareTo(this.name); } }
1.2Comparator接口
①實(shí)現(xiàn)Comparable接口的操作:
②通過該接口實(shí)現(xiàn)的姓名的比較:
③升序降序
執(zhí)行后的結(jié)果:
④優(yōu)點(diǎn)
靈活,對(duì)類的傾入性不強(qiáng)
⑤整體代碼如下:
import java.util.Arrays; import java.util.Comparator; class Student { public int age; public String name; public double score; public Student(int age, String name, double score) { this.age = age; this.name = name; this.score = score; } @Override public String toString() { return "Student{" + "age=" + age + ", name='" + name + '\'' + ", score=" + score + '}'; } } class AgeComparator implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return o1.age-o2.age; } } class ScoreComparator implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return (int)(o1.score-o2.score); } } class NameComparator implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return o1.name.compareTo(o2.name); } } public class Test { public static void main2(String[] args) { Student students1 = new Student(1,"bit",98.9); Student students2 = new Student(2,"abc",88.9); /* if(students1.compareTo( students2) > 0) { }*/ //System.out.println(students1.compareTo( students2)); AgeComparator ageComparator = new AgeComparator(); System.out.println(ageComparator.compare(students1,students2)); } public static void main(String[] args) { Student[] student = new Student[3]; student[0] = new Student(12,"lisi",98.9); student[1] = new Student(6,"zangwu",88.9); student[2] = new Student(18,"whangsan",18.9); System.out.println(Arrays.toString(student)); AgeComparator ageComparator = new AgeComparator(); ScoreComparator scoreComparator = new ScoreComparator(); NameComparator nameComparator = new NameComparator(); Arrays.sort(student,nameComparator);//默認(rèn)是從小到大的排序 System.out.println(Arrays.toString(student)); } public static void main1(String[] args) { int[] array = {1,21,3,14,5,16}; System.out.println(Arrays.toString(array)); Arrays.sort(array); System.out.println(Arrays.toString(array)); } }
2、Cloneable接口
①如何實(shí)現(xiàn)Cloneable接口:
Object 類中存在一個(gè) clone 方法, 調(diào)用這個(gè)方法可以創(chuàng)建一個(gè)對(duì)象的 "拷貝". 但是要想合法調(diào)用 clone 方法, 必須要先實(shí)現(xiàn) Clonable 接口, 否則就會(huì)拋出 CloneNotSupportedException
異常。
a.實(shí)現(xiàn)Cloneable接口
b.重寫Cloneable方法
c.拋異常,強(qiáng)制類型轉(zhuǎn)換
②面試中常問問題:
你知道Cloneable接口嗎?為什么它是一個(gè)空接口,它有什么作用呢?
空接口,標(biāo)志接口,代表這個(gè)類是可以被克隆的
③克隆的原理圖:
④整體代碼的實(shí)現(xiàn):
class Person implements Cloneable{ public int age; public void eat(){ System.out.println("吃!"); } @Override public String toString() { return "Person{" + "age=" + age + '}'; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class TestDemo { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); person.age=13; Person person2=(Person)person.clone(); System.out.println(person2); System.out.println(person); System.out.println("==========="); person2.age=14; System.out.println(person); System.out.println(person2); } }
2.1深拷貝和淺拷貝
①深淺拷貝:
決定是深拷貝還是淺拷貝,并不是方法的用途,而是代碼的實(shí)現(xiàn)
②淺拷貝示例
淺拷貝代碼如下:
class Money implements Cloneable{ public double m = 12.5; } class Person implements Cloneable{ public int age; public Money money = new Money(); public void eat() { System.out.println("吃!"); } @Override public String toString() { return "Person{" + "age=" + age + '}'; } @Override protected Object clone() throws CloneNotSupportedException { Person tmp = (Person)super.clone(); return tmp; } } public class TestDemo { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); Person person2 = (Person)person.clone(); System.out.println(person.money.m); System.out.println(person2.money.m); System.out.println("====================="); person2.money.m = 98.5; System.out.println(person.money.m); System.out.println(person2.money.m); } }
③深拷貝示例:(將tmp中的money也進(jìn)行拷貝)
深拷貝代碼如下:
class Money implements Cloneable{ public double m = 12.5; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class Person implements Cloneable{ public int age; public Money money = new Money(); public void eat() { System.out.println("吃!"); } @Override public String toString() { return "Person{" + "age=" + age + '}'; } @Override protected Object clone() throws CloneNotSupportedException { Person tmp = (Person)super.clone(); tmp.money = (Money) this.money.clone(); return tmp; //return super.clone(); } } public class TestDemo { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); Person person2 = (Person)person.clone(); System.out.println(person.money.m); System.out.println(person2.money.m); System.out.println("====================="); person2.money.m = 98.5; System.out.println(person.money.m); System.out.println(person2.money.m); } }
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Java數(shù)據(jù)結(jié)構(gòu)之實(shí)現(xiàn)跳表
今天帶大家來學(xué)習(xí)Java數(shù)據(jù)結(jié)構(gòu)的相關(guān)知識(shí),文中對(duì)用Java實(shí)現(xiàn)跳表作了非常詳細(xì)的圖文解說及代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下2021-05-05Spring Boot高級(jí)教程之使用Redis實(shí)現(xiàn)session共享
這篇文章主要為大家詳細(xì)介紹了Spring Boot高級(jí)教程之使用Redis實(shí)現(xiàn)session共享,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10Java 回調(diào)機(jī)制(CallBack) 詳解及實(shí)例代碼
這篇文章主要介紹了 Java 回調(diào)機(jī)制(CallBack) 詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02RocketMQ生產(chǎn)者一個(gè)應(yīng)用不能發(fā)送多個(gè)NameServer消息解決
這篇文章主要為大家介紹了RocketMQ生產(chǎn)者一個(gè)應(yīng)用不能發(fā)送多個(gè)NameServer消息原因及解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Java如何基于okhttp請(qǐng)求SSE接口流式返回詳解
對(duì)于流式返回,Spring Boot提供了兩種不同的方式,下面這篇文章主要給大家介紹了關(guān)于Java如何基于okhttp請(qǐng)求SSE接口流式返回的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-03-03SpringBoot集成mybatis連接oracle的圖文教程
這篇文章主要介紹了Spring Boot集成mybatis連接oracle的圖文教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02