JavaSE中比較器、深拷貝淺拷貝舉例詳解
Comparable接口
我們像寫一個Dog類,類中包含成員變量年齡和名字。來方便以下講解。
public class Dog { public int age; public String name; @Override public String toString() { return "Dog{" + "age=" + age + ", name='" + name + '\'' + '}'; } }
當(dāng)我們要對自己的自定義類進(jìn)行直接比較時會發(fā)現(xiàn)不能比較,這是因為這些操作符只能比較基本數(shù)據(jù)類型。
public static void main(String[] args) { Dog dog1 = new Dog(6,"xiaohei"); Dog dog2 = new Dog(7,"xiaobai"); System.out.println(dog1 > dog2); }
單個比較
如果要實現(xiàn)比較功能,我們就要實現(xiàn)Comparable接口,并將其中的compareTo方法重寫,在“繼承”時將泛型寫為當(dāng)前類:
public class Dog implements Comparable<Dog> { private int age; public int compareTo(Dog o) { return this.age - o.age; } }
在實現(xiàn)后就可以在main函數(shù)中調(diào)用compareTo方法來比較:
public static void main(String[] args) { Dog dog1 = new Dog(6,"xiaohei"); Dog dog2 = new Dog(7,"xiaobai"); System.out.println(dog1 .compareTo(dog2)); }
從這我們可以看見這個比較方法是通過對象的引用來實現(xiàn),如果要進(jìn)行多個對象比較酒不行呢。
多個比較
我們多個比較就可以通過數(shù)組來實現(xiàn),將對象放入數(shù)組中進(jìn)行排序,因為我們實現(xiàn)了Comparable接口,我們調(diào)用Arrays.sort()方法就行:
public static void main(String[] args) { Dog dog1 = new Dog(6,"xiaohei"); Dog dog2 = new Dog(7,"xiaobai"); Dog dog3 = new Dog(5,"xiaodog"); Dog dog4 = new Dog(8,"wangcai"); Dog[] dogs = new Dog[]{dog1,dog2,dog3,dog4}; Arrays.sort(dogs); for (int i = 0; i < dogs.length; i++) { System.out.println(dogs[i].toString()); } }
Comparator接口
在實現(xiàn)了Compareable接口后我們就直接將比較方法定死了,不能進(jìn)行比較條件的修改。如果要解決這個問題就可以使用Comparator接口。
我們就在重新寫個類來用于Dog類的名字比較,將compare方法重寫:
import java.util.Comparator; public class NameComparator implements Comparator<Dog> { @Override public int compare(Dog o1, Dog o2) { return o1.getName().compareTo(o2.getName()); } }
然后再主函數(shù)中實例化該對象,再在調(diào)用Arrays.sort()
的時候?qū)⒃搶ο笠黄饌魅刖涂梢詫崿F(xiàn)以名字排序,如果是要用年齡排序就按同樣方法寫出年齡排序的類,然后Arrays.sort()
調(diào)用的時候傳該類就行。
public static void main(String[] args) { Dog dog1 = new Dog(6,"xiaohei"); Dog dog2 = new Dog(7,"xiaobai"); Dog dog3 = new Dog(5,"xiaodog"); Dog dog4 = new Dog(8,"wangcai"); Dog[] dogs = new Dog[]{dog1,dog2,dog3,dog4}; NameComparator nameComparator = new NameComparator(); Arrays.sort(dogs,nameComparator); for (int i = 0; i < dogs.length; i++) { System.out.println(dogs[i].toString()); } }
Compareable接口,Comparetor接口,equals方法對比
因為所有類都有一個共同父類Object,Object類中有equals方法,我們將該方法重寫也可以比較
public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Dog dog = (Dog) o; return age == dog.age && Objects.equals(name, dog.name); }
Compareable接口實現(xiàn)的比較會導(dǎo)致比較方法定死了,Comparetor實現(xiàn)的比較器就可以改變比較的方法,兩個都返回int數(shù)字,而equals方法只是單純比較是否相等并且返回值是boolean類型
深拷貝與淺拷貝
拷貝
我們要直接將我們的一個對象給到新對象,像基本數(shù)據(jù)類型那樣用=肯定是不行的,這就需要用到clone方法了:
步驟如下
1.在類中重寫clone方法,因為clone方法是Object類的,直接重寫就行
2.實現(xiàn)Cloneable接口,該接口是一個空接口,但是必須實現(xiàn)該接口來表示當(dāng)前類可以克隆。
public class Dog implements Cloneable { public String name; public int age; protected Object clone() throws CloneNotSupportedException { return super.clone(); } public Dog(String name, int age) { this.age = age; this.name = name; } }
3.在調(diào)用克隆的方法還要實現(xiàn)異常throws CloneNotSupportedException
4.調(diào)用clone還用向下轉(zhuǎn)型
public static void main(String[] args) throws CloneNotSupportedException { Dog dog1 = new Dog("xiaohei",6); Dog dog2 = (Dog)dog1.clone(); }
深拷貝淺拷貝區(qū)別
二者區(qū)別就在與如果當(dāng)前類還有其他類的對象時,該拷貝是否將該對象一起拷貝。
如果重新開辟了空間拷貝過去了,那就是深拷貝,
如果沒有還是指向原來的空間,那就是淺拷貝。
如果要實現(xiàn)深拷貝就在我們類中重寫的clone方法中將類中對象也clone,并且類中對象所在類也實現(xiàn)了克?。?/strong>
class Price implements Cloneable { protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class Dog implements Cloneable { public String name; public int age; Price price = new Price(); protected Object clone() throws CloneNotSupportedException { return super.clone(); } public Dog(String name, int age) { this.age = age; this.name = name; } }
總結(jié)
到此這篇關(guān)于JavaSE中比較器、深拷貝淺拷貝的文章就介紹到這了,更多相關(guān)JavaSE比較器、深拷貝淺拷貝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于@SpringBootApplication與@SpringBootTest的區(qū)別及用法
這篇文章主要介紹了關(guān)于@SpringBootApplication與@SpringBootTest的區(qū)別及用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01springboot中項目啟動時實現(xiàn)初始化方法加載參數(shù)
這篇文章主要介紹了springboot中項目啟動時實現(xiàn)初始化方法加載參數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12idea無法打斷點,單擊或雙擊代碼行左側(cè)區(qū)域無效的解決
這篇文章主要介紹了idea無法打斷點,單擊或雙擊代碼行左側(cè)區(qū)域無效的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09SSH框架網(wǎng)上商城項目第20戰(zhàn)之在線支付平臺
這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項目第20戰(zhàn)之在線支付平臺,關(guān)于第三方支付的內(nèi)容從本文開始,感興趣的小伙伴們可以參考一下2016-06-06Spring?IOC容器FactoryBean工廠Bean實例
這篇文章主要為大家介紹了Spring?IOC容器FactoryBean工廠Bean實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05