【學習筆記】Java基礎知識——泛型與集合

來源:互聯網
上載者:User

標籤:list   系統   類型   萬用字元   設計   資料   高效   解決   end   

1.為什麼要使用泛型(generic)程式設計?

在《Java核心技術》中的闡述:編寫的代碼可以被許多不同類型的對象所重用,這樣就允許泛型代碼和遺留代碼之間能夠相互操作。

提到的兩個概念:型別參數萬用字元類型

在《Head first Java》中的解釋似乎更通俗易懂些:幾乎所有以泛型編寫的程式都與處理集合有關,雖然泛型可以用在其他地方,但它主要目的還是讓你能夠寫成有型別安全的集合,也就是說編譯器能夠幫忙防止你把Dog加到一群Cat中。

就像在Collection類的sort方法中有寫明:public static <T extends Comparable<?super T>>void sort (List<T> list)其中Comparable<?super T>就是在對參數類型做限制,加入的是什麼對象,返回的還是該對象的引用。

在泛型功能出現前,編譯器無法注意到你加入集合中的東西是什麼,因為所有的集合都寫成處理Object類型,可以把任何東西放進ArrayList中,有點像ArrayList<Object>

在Java的程式或檔案中只要用到<>這組符號, 就表示泛型正在作用—它是一種從Java 5.0開始加入的特質。

ArrayList雖然是最常用的,但偶爾還是會有特殊情況,比如ArrayList沒有排序方法。下面列出幾個重要的:

LinkedList:針對經常插入或刪除中間元素所設計的高效率集合(實際上ArrayList還是比較實用)

TreeSet:以有序狀態保持並防止重複

(TreeSet的元素必須是Comparable

使用TreeSet,下列其中一項必須為真

集合中的元素必須是有實現Comparable的類型

使用重載,取用Comparator參數的建構函式來建立TreeSet

HashSet:防止重複的集合,可快速地找到相符的元素。(但是要override hashcode()和equals()這兩個方法)

HashMap:可用成對的name/value來儲存於取出

LinkedHashMap:類似HashMap,但是可記住元素插入的順序,也可以設定成按照元素上次存取的先後來排序。

 

關於泛型

1)         建立被泛型化類(例如ArrayList)的執行個體

建立ArrayList時你必須要指定它所容許的對象,就像單純的數組那樣。

new ArrayList<Song>()

2)         聲明與指定泛型型別的變數

多態遇到泛型型別會怎麼樣?

數組與ArrayList

對於ArrayList,如果把方法聲明成取用ArrayList<Animal>,它就智慧取用ArrayList< Animal >參數,ArrayList< Animal的子類>就行,而數組就可以實現。

數組的類型是在運行期間檢查的,但集合的類型檢查只會發生在編譯期間,所以如果出現類型錯誤,對於集合來說,編譯是都無法通過的。

泛型與多態

萬用字元?:用來接受Animal子型參數的方法

public void takeAnimals (ArrayList<? extends Animal> animals){   ……

}

extends同時代表繼承和實現

List<Song> songlist=new ArrayList<Song>()

1)         聲明(與調用)取用泛型型別的方法

聲明:void foo(List<Song> list)

調用x.foo(songList)

總結:主要就是泛型類,泛型變數,泛型方法。

註:API的設計團隊已經涵蓋了大部分你會遇到的額資料結構,而幾乎只有集合會真的需要泛型。

 

使用泛型的類

ArrayList是最常用的泛型化類型,我們從查看它的說明檔案說起。

public class ArrayList<E> extends Abstraction<E> implements List<E>…{

……

}

其中E就被稱為型別參數

運用泛型的方法

泛型的類代表類的聲明用到型別參數,泛型的方法代表方法的聲明特徵用到型別參數

在方法中的型別參數有幾種不同的運用方式:

1)         使用定義在類聲明的型別參數

public class ArrayList<E> extends AbstracList<E>…{

public boolean add(E o)

2)         使用未定義在類聲明的型別參數

public <T extends Animal> void takeThing(ArrayList<T> list)

代表傳入Animal或其子型來出初始化ArrayList。

 

從Collection的API說明檔案中我們發現3個主要的介面:List、Set和Map

LIST:對付順序的好幫手

是一種知道索引位置的集合,List知道某物在系列集合中的位置,可以有多個元素引用相同的對象。

SET:注重獨一無二的性質

不允許重複的集合。它知道某物是否已經存在於集合中,不會有多個元素引用相同的對象

MAP:用key來搜尋的專家

使用成對的索引值和資料值。Map會維護與key有關聯的值,兩個key可以引用相同的對象,但是key不能重複,典型的key是String,但也可以是任何對象。

 

集合的API

 

 

 

以上內容來自Head first Java,接下來的內容from 《Java核心技術》 (感覺該書闡述的有點抽象)

泛型程式設計分為3個能力等級:

1)      僅僅使用泛型類

2)      能夠利用Java泛型系統地解決代碼銜接,泛型類混合問題。

3)      實現自己的泛型類和泛型方法。

2.泛型類:具有一個或多個類型變數的類。

pair類引入了一個類型變數T,用角括弧<>括起來,並放在類名後面。

泛型類可以有多個類型變數,例如,也可以這樣定義pair類,其中第一個域和第二個域使用不同的類型:

public class Pair<T,U>{. . .}

3.泛型方法:

如下為定義一個帶有型別參數的簡單方法:

class ArrayAlg

{

         public static <T> T getMiddle(T. . .a)

                   {

                            return a[a.length/2];

                   }

}

類型變數放在修飾符public static的後面,傳回型別的前面。

泛型方法可以定義在普通類中,也可以定義在泛型類中。

4.類型變數的限定

為類型變數實現介面,來達到限定的目的,避免產生編譯錯誤,如,為T實現Comparable介面

public static <T extends Comparable> T getMiddle(T. . .a)

類型擦除:去掉類型變數的限制,或者將類型變數替換為object

橋方法:為解決類型擦除與多態發生衝突的問題

有關Java泛型轉換的事實:

虛擬機器沒有泛型,只有普通的類和方法。

所有的參數類型都用它們的限定類型替換

橋方法被合成來保持多態

為保持型別安全,必要時插入強制類型轉換

【學習筆記】Java基礎知識——泛型與集合

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.