16.集合與泛型

  1. 除了ArrayList外還有這些集合
  • Treeset 以有序狀態(tài)保持并可防止重復(fù)
  • HashMap 可用成對(duì)的name/value來保存與取出
  • LinkedList 針對(duì)經(jīng)常插入或刪除中間元素所設(shè)計(jì)的高效率集合
  • HashSet 防止重復(fù)的集合秽荞,可快速地尋找相符的元素
  • LinkedHashMap 類似HashMap震庭,但可記住元素插入的順序馏谨,也可以設(shè)定成依照元素上次存取的先后來排序
  1. 可以用TreeSet或Collections.sort( )方法對(duì)數(shù)組進(jìn)行按字母排序
  2. 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;
}
  1. 為什么要用泛型?(帶有<>的就是泛型)
  • 運(yùn)用泛型可以創(chuàng)建類型安全更好的集合炕柔,讓問題盡可能在編譯器就能抓到酌泰,而不會(huì)等到執(zhí)行期才冒出來
  • 如果沒有泛型,編譯器會(huì)很愉快地接受你把綿羊?qū)ο笏偷嚼匣⒓现?/li>
  1. 泛型使用須知
    (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í)際上的類型
  1. 使用泛型的方法
  • 使用定義在類聲明的類型參數(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)用該方法
  1. 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比較并輸出
  1. int compareTo(T o)
    比較此對(duì)象與指定對(duì)象的順序羡宙。如果該對(duì)象小于、等于或大于指定對(duì)象掐隐,則分別返回負(fù)整數(shù)狗热、零或正整數(shù)钞馁。
  2. Comparator
  • 使用compareTo()方法時(shí),list中的元素只能有一種將自己與同類的另一個(gè)元素做比較的方法
  • 但Comparator是獨(dú)立與所比較的元素類型之外的——它是獨(dú)立的類
  1. 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

  1. 如何解決數(shù)據(jù)重復(fù)——用Set集合
  2. 集合中的三個(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ì)象
  1. 對(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ì)象也不一定相等)
  1. 覆蓋過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í)例變量
  1. hashCodeequals()的相關(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()等值
  1. 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);
}
  1. 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);
        }
  1. 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ù)蚪缀,返回它的值
}
  1. 數(shù)組的類型是在運(yùn)行期間檢查的,但集合的類型檢查只會(huì)發(fā)生在編譯期間
  2. 萬用字符<?>
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)的畴。
  1. 相同功能的另一種語法
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)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市煎娇,隨后出現(xiàn)的幾起案子二庵,更是在濱河造成了極大的恐慌,老刑警劉巖缓呛,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件催享,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡哟绊,警方通過查閱死者的電腦和手機(jī)因妙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來匿情,“玉大人兰迫,你說我怎么就攤上這事【娉疲” “怎么了汁果?”我有些...
    開封第一講書人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長玲躯。 經(jīng)常有香客問我据德,道長鳄乏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任棘利,我火速辦了婚禮橱野,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘善玫。我一直安慰自己水援,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開白布茅郎。 她就那樣靜靜地躺著蜗元,像睡著了一般。 火紅的嫁衣襯著肌膚如雪系冗。 梳的紋絲不亂的頭發(fā)上奕扣,一...
    開封第一講書人閱讀 49,785評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音掌敬,去河邊找鬼惯豆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛奔害,可吹牛的內(nèi)容都是我干的楷兽。 我是一名探鬼主播,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼舀武,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼拄养!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起银舱,我...
    開封第一講書人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤瘪匿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后寻馏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棋弥,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年诚欠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了顽染。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡轰绵,死狀恐怖粉寞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情左腔,我是刑警寧澤唧垦,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站液样,受9級(jí)特大地震影響振亮,放射性物質(zhì)發(fā)生泄漏巧还。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一坊秸、第九天 我趴在偏房一處隱蔽的房頂上張望麸祷。 院中可真熱鬧,春花似錦褒搔、人聲如沸阶牍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荸恕。三九已至,卻和暖如春死相,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背咬像。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工算撮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人县昂。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓肮柜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親倒彰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子审洞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 上一篇文章介紹了Set集合的通用知識(shí)。Set集合中包含了三個(gè)比較重要的實(shí)現(xiàn)類:HashSet待讳、TreeSet和En...
    Ruheng閱讀 15,625評(píng)論 3 57
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法芒澜,類相關(guān)的語法,內(nèi)部類的語法创淡,繼承相關(guān)的語法痴晦,異常的語法,線程的語...
    子非魚_t_閱讀 31,598評(píng)論 18 399
  • java筆記第一天 == 和 equals ==比較的比較的是兩個(gè)變量的值是否相等琳彩,對(duì)于引用型變量表示的是兩個(gè)變量...
    jmychou閱讀 1,488評(píng)論 0 3
  • 3.3 集合 一方面誊酌, 面向?qū)ο笳Z言對(duì)事物的體現(xiàn)都是以對(duì)象的形式,為了方便對(duì)多個(gè)對(duì)象的操作露乏,就要對(duì)對(duì)象進(jìn)行存儲(chǔ)碧浊。另...
    閆子揚(yáng)閱讀 722評(píng)論 0 1
  • 陽春三月,窗外跳躍著細(xì)細(xì)碎碎的陽光瘟仿,我隨意打開QQ好友箱锐,發(fā)現(xiàn)了以前的一位同事,發(fā)過去一個(gè)簡(jiǎn)短的問候:“你好猾骡!”對(duì)方...
    董燦閱讀 727評(píng)論 0 3