- 除了ArrayList外還有這些集合
-
Treeset
以有序狀態(tài)保持并可防止重復(fù) -
HashMap
可用成對(duì)的name/value來保存與取出 -
LinkedList
針對(duì)經(jīng)常插入或刪除中間元素所設(shè)計(jì)的高效率集合 -
HashSet
防止重復(fù)的集合秽荞,可快速地尋找相符的元素 -
LinkedHashMap
類似HashMap震庭,但可記住元素插入的順序馏谨,也可以設(shè)定成依照元素上次存取的先后來排序
- 可以用TreeSet或Collections.sort( )方法對(duì)數(shù)組進(jìn)行按字母排序
- toString( )
- 因?yàn)閠oString( )是定義在Object類中的第煮,所以Java中的每個(gè)類都會(huì)繼承toString( )诫尽,又因?yàn)閷?duì)象被System.out.println(anObject)列出來時(shí)會(huì)被調(diào)用toString( )始鱼,所以當(dāng)你把list列出時(shí)惹悄,每個(gè)對(duì)象的toString( )都會(huì)被調(diào)用一次阔挠。
public String toString(){
return title;
}
- 為什么要用泛型?(帶有<>的就是泛型)
- 運(yùn)用泛型可以創(chuàng)建類型安全更好的集合炕柔,讓問題盡可能在編譯器就能抓到酌泰,而不會(huì)等到執(zhí)行期才冒出來
- 如果沒有泛型,編譯器會(huì)很愉快地接受你把綿羊?qū)ο笏偷嚼匣⒓现?/li>
- 泛型使用須知
(1)創(chuàng)建被泛型化類(如ArrayList)的實(shí)例new ArrayList<Song>();
(2)聲明與指定泛型類型的變量List<Song> songList = new ArrayList<Song>();
(3)聲明(與調(diào)用)取用泛型類型的方法匕累。void foo(List<Song> list);
6.ArrayList的說明文件
public class ArrayList<E> extends AbstractList<E> implements List<E>...{
E部分會(huì)用你所聲明與創(chuàng)建的真正類型來替代
public boolean add(E o);//E用來指示可以加入ArrayList的元素類型
}E代表用來創(chuàng)建與初始ArrayList的類型陵刹,當(dāng)你看到ArrayList文件上的E時(shí),就可以把它換成實(shí)際上的類型
- 使用泛型的方法
- 使用定義在類聲明的類型參數(shù)
public class ArrayList<E> extends AbstractList<E>...{
public boolean add(E o);只能在此使用E欢嘿,因?yàn)樗呀?jīng)被定義成類的一部分
- 使用未定義在類聲明的類型參數(shù)
public <T extends Animal> void takeThing(ArrayList<T> list)
可以傳入Animal或任何Animal的子型(如Cat或Dog)衰琐,可以使用ArrayList<Dog>來調(diào)用該方法
- sort()方法只能接受Comparable對(duì)象的list。
public static <T extends Comparable<? super T>> void sort(List<T> list)
這表示它必須是Comparable 僅能傳入繼承Comparable的參數(shù)化類型的list
因此炼蹦,只要讓要排序的類(比如Song)實(shí)現(xiàn)Comparable就行了
class Song implements Comparable<Song>{
public int comparaTo(Song s){
return title.compareTo(s.getTitle());
用compareTo()方法將執(zhí)行方法的Song與傳入的Song比較并輸出
-
int compareTo(T o)
比較此對(duì)象與指定對(duì)象的順序羡宙。如果該對(duì)象小于、等于或大于指定對(duì)象掐隐,則分別返回負(fù)整數(shù)狗热、零或正整數(shù)钞馁。 - Comparator
- 使用compareTo()方法時(shí),list中的元素只能有一種將自己與同類的另一個(gè)元素做比較的方法
- 但Comparator是獨(dú)立與所比較的元素類型之外的——它是獨(dú)立的類
- compareTo()與Caomparator比較
- 調(diào)用單一參數(shù)的
sort(List o)
方法代表由List元素上的compareTo()
方法來決定順序匿刮。因此元素必須要實(shí)現(xiàn)Comparable這個(gè)接口 - 調(diào)用兩個(gè)參數(shù)的
sort(List o,Compararot c)
方法代表不會(huì)調(diào)用list元素的compareTo()
方法僧凰,而會(huì)使用Comparator的compare()
方法。這意味著list元素不需要實(shí)現(xiàn)Comparable
class ArtistCompare implements Comparator<Song>{
public int Compare(Song one,Song two){
return one.getArtist().compareTo(two.getArtist());
} 這會(huì)返回String ,以String來比較
}
public void go(){
...
ArtistCompare artistCompare = new AritstCompare();
Collections.sort(songList,artistCompare);
}
2
- 如何解決數(shù)據(jù)重復(fù)——用Set集合
- 集合中的三個(gè)主要接口——List Set Map
- List——對(duì)付順序的好幫手(是一種知道索引位置的集合熟丸,可重復(fù))
List知道某物在系列集合中的位置训措,可以由多個(gè)元素引用相同的對(duì)象 - SET——注重獨(dú)一無二的性質(zhì)(不允許重復(fù)的集合,不會(huì)重復(fù))
它知道某物是否已存在與集合中光羞,不會(huì)有多個(gè)元素引用相同的對(duì)象 - MAP——用Key來搜索的專家(值可以重復(fù)绩鸣,但key不行)
兩個(gè)key可以引用相同的對(duì)象,但key不能重復(fù)纱兑,典型的key會(huì)是String呀闻,但也可以是任何對(duì)象
- 對(duì)象怎樣才算相等?
- 引用相等性——堆上同一個(gè)對(duì)象的兩個(gè)引用
可以用==來比較兩個(gè)引用是否相等 - 對(duì)象相等性——堆上的兩個(gè)不同對(duì)象在意義上是相同的
如果想要把兩個(gè)不同的對(duì)象視為相等的萍启,就必須覆蓋過從Object繼承下來的hashCode()
方法與equals
方法
4.HashSet如何檢查重復(fù):hashCode()
與equals()
- 當(dāng)你把對(duì)象加入HashSet時(shí)总珠,它會(huì)使用對(duì)象的hashCode值來判斷對(duì)象加入的位置。但同時(shí)也會(huì)與其他已經(jīng)加入的對(duì)象的hashCode作比對(duì)勘纯,如果沒有相符的hashCode局服,HashSet就會(huì)假設(shè)新對(duì)象沒有重復(fù)出現(xiàn)。
也就是說驳遵,如果hashCode不同淫奔,則HashSet會(huì)假設(shè)對(duì)象不可能是相同的(但有相同hashCode的對(duì)象也不一定相等)
- 覆蓋過
hashCode()
與equals()
的Song類
public boolean equals(Object aSong){ //aSong是要被比較的對(duì)象
Song s = (Song) aSong;
return getTitle().equals(s.getTitle));
}//因?yàn)楦杳荢tring,且String本來就覆蓋過的equals(),所以我們可以調(diào)用它
public int hashCode(){
return title.hashCode();
}//String也有覆蓋過的hashCode()堤结,注意到hashCode()與equals()使用相同的實(shí)例變量
-
hashCode
與equals()
的相關(guān)規(guī)定
- 如果兩個(gè)對(duì)象相等唆迁,則hashcode必須也是相等的
- 如果兩個(gè)對(duì)象相等拓颓,對(duì)其中一個(gè)對(duì)象調(diào)用equals()必須返回true卖陵,也就是說,若a.equas(b)卑惜,則b.equals(a)
- 如果兩個(gè)對(duì)象有相同的hashCode值瘾带,它們也不一定是相等的鼠哥。但若兩個(gè)對(duì)象相等,則hashCode值一定是相等的
- 因此若equals()被覆蓋過看政,則hashCode()也必須被覆蓋
- hashCode()的默認(rèn)行為是對(duì)在heap上的對(duì)象產(chǎn)生獨(dú)特的值朴恳。如果你沒有override過hashCode(),則該class的兩個(gè)對(duì)象怎樣都不會(huì)被認(rèn)為是相同的
- equals()的默認(rèn)行為是執(zhí)行==的比較允蚣。也就是說會(huì)去測(cè)試兩個(gè)引用是否是否對(duì)上heap上的同一個(gè)對(duì)象于颖。如果equals()沒有被覆蓋過,兩個(gè)對(duì)象永遠(yuǎn)都不會(huì)被視為相同的嚷兔,因?yàn)椴煌膶?duì)象有不同的字節(jié)組合森渐。
a.equals(b)
必須與a.hashCode() == b.hashCode()
等值
但a.hashCode() == b.hashCode()
不一定要與a.equals()
等值
- TreeSet
TreeSet在防止重復(fù)上面與HashSe一樣做入。但它還會(huì)一直保持集合處于有序狀態(tài)。
public void go(){ //調(diào)用沒有參數(shù)的構(gòu)造函數(shù)來用TreeSet
... //取代HashSet意味著以對(duì)象的compareTo()方法來進(jìn)行排序
TreeSet<Song> songSet = new TreeSet<Song>();
songSet.addAll(songList);
}
- TreeSet的元素必須是Comparable
要使用TreeSet章母,下列其中一項(xiàng)必須為真
- 集合中的元素必須是有實(shí)現(xiàn)Comparable的類型
class Book implements Comparable{
String title;
public Book(String t){
title = t;
}
public int compareTo(Object b){
Book book = (Book) b;
return (title.compareTo(book.title));
}
}
- 使用重載母蛛、取用Comparator參數(shù)的構(gòu)造函數(shù)來創(chuàng)建TreeSet
public class BookCompare implements Comparator<Book>{
public int compare(Book one,Book two){
return (one.title.compareTo(two.title));
}
}
class Test{
public void go(){
BookCompare bCompare = new BookCompare();
TreeSet<Book> tree = new TreeSet<Book>(bCompare);
}
- Map
Map中的元素實(shí)際上是兩個(gè)對(duì)象:關(guān)鍵字和值翩剪,值可以重復(fù)乳怎,但是key不行
public static void main(String[] args){//hashMap需要兩個(gè)參數(shù),關(guān)鍵字和值
hashMap<String,Integer> scores = new hashMap<String,Integer>();
scores.put("kathy",42);
scores.put("Bert",343);//使用put()取代add()前弯,它需要兩個(gè)參數(shù)
System.out.println(scores);
System.out.println(scores.get("Bert"));//get()取用關(guān)鍵字參數(shù)蚪缀,返回它的值
}
- 數(shù)組的類型是在運(yùn)行期間檢查的,但集合的類型檢查只會(huì)發(fā)生在編譯期間
- 萬用字符
<?>
public void takeAnimals(ArrayList<? extends Animals> animals) {
...} //此處的extends同時(shí)代表繼承和實(shí)現(xiàn)
- 在方法中使用萬用字符時(shí)恕出,編譯器會(huì)阻止任何可能破壞引用參數(shù)所指集合的行為
- 你能夠調(diào)用List中任何元素的方法询枚,但不能加入元素
- 也就是說,你可以操作集合元素浙巫,但不能新增集合元素金蜀。如此才能保證執(zhí)行期間的安全性,因?yàn)榫幾g器會(huì)阻止執(zhí)行期的恐怖行動(dòng)的畴。
- 相同功能的另一種語法
public <T extends Animal> void takeThing(ArrayList<T> list)
- 如果都一樣渊抄,為什么要用有?那個(gè)
這要看你是否會(huì)用到T來決定丧裁,如果方法有兩個(gè)參數(shù)护桦,則可以
public <T extends Animals> void takeThing(ArrayList<T> one,ArrayList<T> two)
而不必這樣
public void takeThing(ArrayList<? extends Animal> one,ArrayList<? extends Animals> two)