Java中的集合(一):泛型

在JavaSE 1.5中,Java引入泛型的概念恢总。那么何為泛型呢迎罗?
  泛型就是將類型參數(shù)化,也就是說將所操作的數(shù)據(jù)類型指定為一個參數(shù)片仿,從而使代碼可以復用纹安,并且引入泛型意味著更好的類型安全。
  泛型可以被使用到類砂豌、接口和方法中厢岂。
  泛型的使用在集合中尤為突出。

一阳距、定義&使用

在定義泛型類咪笑、泛型接口或泛型方法使,在<>中指定一個或多個類型參數(shù)的名字娄涩。對于類型參數(shù)的名字可以使用任何Java標識符(由字符窗怒、數(shù)字映跟、下劃線(_)、美元符($)組成扬虚,不能以數(shù)字開頭)努隙,但為了規(guī)范化和達到見名知意的目的,建議使用簡練的名字辜昵,多使用單個字符荸镊,并且最好避免小寫字母。
  在這里建議大家多看看Java API的源碼堪置,并不一定要看懂程序躬存,而是看那些大牛的編碼風格,命名風格舀锨,很值得去學習一下岭洲。
比如在API中的類型參數(shù)名字:E (Element)元素
             K (Key)鍵
             V (Value) 值
就像這樣

//泛型接口
public interface Test<E>{}

//單個類型參數(shù)的泛型類
public class Test1<E> {
   public void test(E e){}
}

//多個類型參數(shù)的泛型類
public class Test2<K,V>{}

二、泛型方法

泛型接口和泛型類在聲明上相對簡單些坎匿,看上面的例子就可以了盾剩,對于泛型方法,我們看API中的一個例子替蔬,在java.util.Collections有一個對集合按照某種規(guī)則進行排序的方法sort(),方法如下:

public static <T extends Comparable<? super T>> void sort(List<T> list){//...}

泛型方法的聲明需要在返回值前面進行泛型的生命告私,和泛型類和泛型接口一樣,可以聲明多個泛型承桥,用英文逗號隔開驻粟。
  泛型方法使我們可以使用未定義在類聲明中的類型參數(shù)。

三凶异、規(guī)則&限制

1.泛型的類型參數(shù)只能是類類型格嗅,不能是簡單類型。
List<int> list = new ArrayList<int>();
/*這樣寫也是錯誤唠帝,是自己粗心大意屯掖,有些想當然了。如果由于自己的失誤給大家?guī)?   誤解襟衰,在這里向大家表示歉意贴铜。
*/
2.泛型的類型參數(shù)可以使用extends語句,例如:
public class Test<T extends List> {//...}

在以上的類聲明中類型參數(shù)只能是List的子類瀑晒,不能為其他類類型 绍坝。請注意,在這里extends關鍵字不能理解成繼承的意思苔悦,因為在這里extends既適用于類也適用于接口轩褐,就如上面那樣,所以在這里extends應該理解為“是一個”的意思玖详。

3.泛型的類型參數(shù)可以有多個把介,就像API中的Map一樣勤讽,
public interface Map<K,V>{//...}
4.同一種泛型對應多個版本,因為參數(shù)類型是不確定的拗踢,但是不同版本的泛型類實例是不兼容的脚牍,包括具有繼承關系的類類型。下面看下面這個例子巢墅。
public class Test{
  public static void test(List<Animal> list){}
  static class Animal{}
  static class Dog extends Animal{}
  static class Cat extends Animal{}
  public static void main(String[] args){
    //創(chuàng)建Animal類型的集合
    List<Animal> animalList = new ArrayList<Animal>();
    animalList.add(new Animal());
    //由于Dog和Cat類繼承自Animal诸狭,所以也可以說Dog和Cat也是Animal類型的,所以可以網(wǎng)Animal類型的集合中添加Dog和Cat的實例
    animalList.add(new Dog());
    animalList.add(new Cat());
    //創(chuàng)建Dog類型的集合
    List<Dog> dogList = new ArrayList<Dog>();
    dogList.add(new Dog());
    dogList.add(new Dog());
    //調(diào)用test方法
    test(animalList);
    test(dogList);//編譯器將會報錯
    }
}

在上面的實例中我們首先定義了一個接收Animal類型集合作為參數(shù)的test方法君纫,然后再Main主方法中分別定義了Animal類型和Dog類型的List集合驯遇。
接下來我們調(diào)用test方法將animalListdogList作為參數(shù)傳進去,
這時我們會發(fā)現(xiàn)test(dogList)會報錯蓄髓。
  這是因為將子類集合加入到具有聲明為父類集合的參數(shù)的方法中是不合法的操作叉庐,也就是我們上面說的不同版本的泛型類實例是不兼容的。
  那么你可能要疑問:那么我該怎樣使用多態(tài)化集合參數(shù)呢双吆?
  方法1.使用通配符類型眨唬?会前,就像下面這樣

...
public static void test(List<?> list){}
...
public static void main(String[] args){
  ...
  test(animalList);
  test(dogList);//這樣編譯器就不會報錯了
}

方法2.在聲明泛型時使用extends語句

...
public static <T extends Animal> void test(List<T> list){}
...
public static void main(String[] args){
  ...
  test(animalList);
  test(dogList);//這樣編譯器就不會報錯了
}

<b>注意</b>:使用上面兩種方式時好乐,編譯器會組織任何可能破壞形式參數(shù)所指集合的行為,也就是不能在定義的方法中瓦宜,不能向作為參數(shù)的集合中添加任何元素蔚万,但可以刪除元素。

三临庇、其他

數(shù)組也是我們經(jīng)常使用的用來存儲數(shù)據(jù)的一種集合
  對于數(shù)組的類型是在運行時期檢查的反璃,對于集合的類型檢查只會發(fā)生在編譯時期。
  所以因為多態(tài)的關系假夺,將子類數(shù)組傳入具有聲明為父類數(shù)組的參數(shù)的方法中是完全合法的操作淮蜈。但是如果將子類數(shù)組傳入到方法中后,對該數(shù)組隨意進行賦值操作已卷,會報ArrayStoreException異常梧田,就行下面這樣。

public class Test {
  public static void test2(Animal[] animals){
    animals[0] = new Cat();
    animals[1] = new Animal();
  }
  public static void main(String[] args){
    Animal[] animals = new Animal[3];
    Dog[] dogs = new Dog[3];
    test2(animals);
    test2(dogs);
  }
}

test2()方法中對參數(shù)數(shù)組進行了賦值操作侧蘸,當將Dog類型的數(shù)組傳入test2()方法中裁眯,在程序運行時會有ArrayStoreException異常。
  因為經(jīng)驗尚淺讳癌,所以如果有錯誤的或者描述不妥的地方穿稳,希望各位讀者幫忙指正。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末晌坤,一起剝皮案震驚了整個濱河市逢艘,隨后出現(xiàn)的幾起案子旦袋,更是在濱河造成了極大的恐慌,老刑警劉巖埋虹,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猜憎,死亡現(xiàn)場離奇詭異,居然都是意外死亡搔课,警方通過查閱死者的電腦和手機胰柑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爬泥,“玉大人柬讨,你說我怎么就攤上這事∨鄯龋” “怎么了踩官?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長境输。 經(jīng)常有香客問我蔗牡,道長,這世上最難降的妖魔是什么嗅剖? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任辩越,我火速辦了婚禮,結(jié)果婚禮上信粮,老公的妹妹穿的比我還像新娘黔攒。我一直安慰自己,他們只是感情好强缘,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布督惰。 她就那樣靜靜地躺著,像睡著了一般旅掂。 火紅的嫁衣襯著肌膚如雪赏胚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天商虐,我揣著相機與錄音觉阅,去河邊找鬼。 笑死称龙,一個胖子當著我的面吹牛留拾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鲫尊,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼痴柔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了疫向?” 一聲冷哼從身側(cè)響起咳蔚,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤豪嚎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谈火,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侈询,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年糯耍,在試婚紗的時候發(fā)現(xiàn)自己被綠了扔字。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡温技,死狀恐怖革为,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舵鳞,我是刑警寧澤震檩,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站蜓堕,受9級特大地震影響抛虏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜套才,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一迂猴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧霜旧,春花似錦错忱、人聲如沸儡率。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽儿普。三九已至崎逃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間眉孩,已是汗流浹背个绍。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留浪汪,地道東北人巴柿。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像死遭,于是被迫代替她去往敵國和親广恢。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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