日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java 泛型和集合_Java集合和泛型

發(fā)布時間:2023/12/19 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 泛型和集合_Java集合和泛型 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

集合

常用的集合有ArrayList,TreeSet,HashMap,HashSet.

ArrayList

最常用的集合,每次插入都在后面追加元素。

TreeSet

以有序狀態(tài)保持并可防止重復。當你需要set集合或元素按照一定的順序排列時,它會很好用。當然,這需要付出一定的成本,每當插入新項目時,它必須要花時間找到適當?shù)奈恢?#xff0c;而ArrayList只要把項目放在最后就行。

TreeSet的元素必須是Comparable的,你必須指出對象應該如何排序。我們已經在上面講過,方法有兩種,分別是:

實現(xiàn)Comparable類。

使用重載,取用Comparator參數(shù)的構造函數(shù)來創(chuàng)建TreeSet,就像sort()的使用一樣。

class ArtistCompare implements Comparator{

public int compare(Song one,Song two){

return one.getAtist().compareTo(two.getArtist());

}

}

ArtistCompare artCompare=new ArtistCompare();

TreeSet tree=new TreeSet(artCompare);

HashMap

針對經常插入或刪除中間元素所設計的高效率集合。

使用方法:

HashMap scores=new HashMap();

scores.put("Kathy",20);

scores.put("Jim",22);

System.out.println(scores.get("Jim"));

HashSet的遍歷方法:

Iterator iter = scores.entrySet().iterator();

while (iter.hasNext()) {

Map.Entry entry = (Map.Entry) iter.next();

Object key = entry.getKey();

Object val = entry.getValue();

String relkey=(String)key;

Integer relval=(Integer) val;

doprocessing();

HashSet

防止重復的集合,可快速的尋找相符的元素。

這里有個問題,對象要怎樣才算相等?是引用到完全相同的對象,還是可以使不同的對象,但是我們所關心的值相等。于是,引出一個關鍵問題:引用相等性和對象相等性。

引用相等性 堆上同一對象的不同引用,如果對這兩個引用調用hashCode(),結果相同。如果沒有被覆蓋的話,hashCode()默認的行為會返回每個對象特定的序號,這個序號一般跟對象的內存位置有關,因此是唯一的。

如果想要知道兩個引用是否相等,可以使用==來比較變量上的字節(jié)組合,如果引用到相同的對象,字節(jié)組合也會一樣。

對象相等性 堆上的兩個不同對象在意義上是相等的,如果你想把兩個不同的對象視為相等,就必須override hashCode()和equals()函數(shù)。

hashCode()

HashSet使用hashcode來達到存取速度較快的存儲方法,如果你嘗試用對象來尋找ArrayList中的相同對象,(不用索引來找),ArrayList會從頭開始找起,但HashSet不是,它是根據(jù)hashcode來找的,不需要從頭找起。

重點在于hashcode相同并不一定保證對象時相等的,學過數(shù)據(jù)結構的同學肯定知道,hashCode()使用的雜湊算法很可能將多個對象傳回相同的雜湊值,越糟糕的雜湊算法越容易碰撞,而且也跟數(shù)據(jù)值域的分布特性有關,因此如果兩個對象的hashcode相同,并不能說它倆就相等,此時還需要使用equals()函數(shù)來進一步確認是否相等。你可以這樣認為,hashcode用來縮小尋找成本,但是最后還需要equals()來確定是否真的找到了相同的對象。

hashCode()的默認行為時對在heap上的對象產生獨特的值,如果你沒有override過,則該class的兩個對象永遠不可能被認為是相同的。

class Song implements Comparable{

String title;

String artist;

public boolean equals(Object aSong ){

Song s = (Song) aSong;

return getTitle.equals(s.getTitle()); //String覆蓋過equals(),我們可以調用。

}

public int hashCode(){

return title.hsahCode(); //String覆蓋過hashCode(),我們直接調用就可以了。

}

public int compareTo(Song s){

return title.compareTo(s.getTitle());

}

public getTitle(){

return title;

}

public getAtirst(){

return artist;

}

}

euqals()

equals()的默認行為是執(zhí)行==的比較,也就是說會去測試兩個引用是否堆上heap上同一個對象,如果eqauls沒有被覆蓋過,兩個對象永遠都不會被視為相同的,因為不同的對象有不同的字節(jié)組合。

toString()

toString()是定義在Object類里的,所以每個java類都會繼承到,且因為對象被System.out.println(anObject)列出來時會調用toString(),所以當你想用被System.out.println輸出你自定義的對象時,你需要重定義toString().

泛型

只要你再java程序或文件中看到<>這一組符號,就代表泛型正在起作用。泛型的主要目的是讓你寫出有類型安全性的集合,也就是,讓編譯器能夠幫忙防止你把Dog放到一群Cat中。

使用泛型的兩種方法:

使用定義在類聲明的類型參數(shù):

public class ArrayList extends AbstractList...{

public boolean add (E o)

...

}

使用未定義在類聲明的參數(shù) public void takeThing (ArrayListlist)

Collections.sort()

Collections.sort()是集合的常用方法,它只接受Comparable對象的list。因此,如果你自定義了一個類,然后生成了很多類對象,并存入集合中,如果你期望用Collections.sort()來對它們進行排序。你需要對你的自定義類做額外的工作。

你有兩種方法:

第一種,實現(xiàn)Comparable 類,并覆蓋它的int compareTo(T o)方法 java.lang.Comparable接口:

public interface Comparable{

int compareTo(T o);

}

class Song implements Comparable{

String title;

String artist;

public int compareTo(Song s){

return title.compareTo(s.getTitle());

}

public getTitle(){

return title;

}

public getAtirst(){

return artist;

}

}

第二種,自制Comparator

使用compareTo()方法時,list中的元素只能有一種將自己與同類型的另一元素相比較的方法。但Comparator是獨立于所比較元素類型之外的--它是獨立的類。因此,你可以有各種不同的比較方法。例如,除了按照title排序,你也可以按照artist排序。

因此,取用Comparator版的sort()方法會用Comparator而不是內置的 compareTo()方法。有如下規(guī)則:

調用單一參數(shù)的sort(List o)方法代表由list元素上的compareTo()方法來決定順序。因此元素必須實現(xiàn)Comparable這個接口。 調用sort(List o,Comparator c)方法代表不會調用list元素的compareTo()方法,而會使用Comparator的compare()方法,這也意味著list元素不用實現(xiàn)

Comparable.

class ArtistCompare implements Comparator{

public int compare(Song one,Song two){

return one.getAtist().compareTo(two.getArtist());

}

}

ArtistCompare artCompare=new ArtistCompare();

Collections.sort(songList,artCompare);

集合的多態(tài)

數(shù)組的多態(tài)

如果方法的參數(shù)是Animal的數(shù)組,它也能夠取用Animal次類型的數(shù)組。

Animal [] animals={new Dog(),new Cat(),new Dog()};

Dog [] dogs={new Dog(),new Dog(),new Dog()};

takeAnimals(animals);

//takeAnimals()能夠存取Animal[]或Dog[]參數(shù),因為Dog也是一個Animal,多態(tài)在此處起作用

takeAnimals(dogs);

public void takeAnimals(Animal [] animals){

for(Animal a : animals){

a.eat();}

}

abstract class Animal{

void eat(){}

}

class Dog extends Animal{

void bark(){}

}

class Cat extends Animal{

void meow(){}

}

ArrayList的多態(tài)

ArrayList animals= new ArrayList();

animals.add(new Dog());

animals.add(new Dog());

animals.add(new Dog());

takeAnimals(animals);

public void takeAnimals(ArrayList animals){

for(Animal a : animals){

a.eat();}

}

因為多態(tài)的關系,編譯器會讓Dog數(shù)組通過取用Animal數(shù)組參數(shù)的方法,這沒有問題,問題是ArrayList< Animal >參數(shù)能接受ArrayList< Dog >嗎,回答是,不行。如果我們在上面的程序里加上這一段,將出現(xiàn)編譯錯誤。

ArrayListdogs = new ArrayList();

dogs.add(new Dog());

dogs.add(new Dog());

takeAnimals(dogs);

可能很多同學會疑惑,畢竟多態(tài)的意義就在于Animal能做的事情,Dog也能做,但你想過嗎,如果我們的takeAnimals()是這樣的:

public void takeAnimals(ArrayList animals){

animals.add(new Cat());

}

這就會有問題了,理論上把Cat加到ArrayList< Animal >是合法的,這也是使用Animal的本意--讓各種Animal都可以加入到此ArrayList中。但是如果你傳入的是一個Dog的ArrayList給該方法,那么將會是Cat強行加入了一個Dog ArrayList中,編譯器當然不會讓這種事情發(fā)生。

所以,如果把方法聲明成ArrayList< Animal >,它只能接受ArrayList< Animal >的參數(shù),ArrayList< Dog>和ArrayList< Cat>都不行。

很多同學肯定又要問了,那為什么數(shù)組可以過關,而ArrayList卻不行,畢竟數(shù)組也會遇到這樣的問題啊。

其實這跟jvm有關,數(shù)組類型是在運行期間檢查的,但集合的類型檢查發(fā)生在編譯期間。

下面這段程序在編譯時不會出錯,但運行時出錯。

Dog [] dogs={new Dog(),new Dog(),new Dog()};

takeAnimals(dogs);

public void takeAnimals(Animal [] animals){

animals[0]=new Cat();

}

那有沒有一種方法,讓我們能夠使用多態(tài)化的集合參數(shù),就像數(shù)組那樣,這樣我們就可以傳入Cat,Dog的集合了,只要我們自己保證不會做出格的行為,比如往Cat集合中加入Dog等等。

萬能的java當然有辦法,使用這種聲明方式:

public void takeThing(ArrayListlist)

當你這樣聲明函數(shù)時,編譯器會阻止任何可能破壞引用參數(shù)所指集合的行為。也就是,你可以調用list中任何元素的方法,但是不能加入元素。

也就是說你可以操作集合元素,但是不能增加集合元素。如此才能保障執(zhí)行期間的安全性。編譯器會阻止執(zhí)行期的恐怖活動。

所以下面的程序是可行的:

for (Animal a :animals){a.eat();}

但這個就過不了編譯:

animals.add(new Cat());

總結

以上是生活随笔為你收集整理的java 泛型和集合_Java集合和泛型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。