1. 程式人生 > >Java基礎總結十七(集合2)

Java基礎總結十七(集合2)

                                                List介面

1.1     介面特點及主要子類

 單列集合

 可存放重複元素

 元素有序

 主要子類

ArrayList:底層資料結構是陣列結構。執行緒不安全的。所以ArrayList的出現替代了Vector。增刪慢,查詢快。

LinkedList:底層是連結串列資料結構。執行緒不安全的,同時對元素的增刪操作效率很高。

Vector:底層資料結構是陣列結構。jdk1.0版本。執行緒安全的。無論增刪還是查詢都非常慢,已被ArrayList替代。

1.2     List介面常用方法

void add(int index, E element)                  //指定索引新增元素

E remove(int index)                                              //移除指定索引處元素

E get(int index)                                             //獲取指定索引元素

E set(int index, E element)                         //修改指定索引元素

List<E> subList(int fromIndex, int toIndex)//擷取指定索引子集

int indexOf(Object o)                                  //返回指定元素索引位置

ListIterator<E> listIterator()         注意:用於應對併發修改異常的返回迭代器方法與迭代器

1.1     具體子類介紹

1.1.1   ArrayList

ArrayList底層資料結構是陣列結構。執行緒不安全的,所以執行速度快,ArrayList的出現替代了Vector。增刪慢,查詢快,由於日常開發中使用最多的功能為查詢資料,遍歷資料,所以ArrayList是最常用的集合。目前市面上許多程式設計師開發時並不嚴謹,非常隨意地使用ArrayList完成任何需求,這種用法是不提倡的。

1.1.2   LinkedList

LinkedList與ArrayList不同,LinkedList是方便新增刪除的List。實際開發中對一個集合元素的新增與刪除經常涉及到首尾操作,索引該具體子類的特點在於提供了大量首尾操作。

public void addFirst(E e)           新增首個元素

public void addLast(E e)           新增最後元素

public E getFirst()                       獲取首個元素

public E getLast()                       獲取最後元素

以及其替代方法

1.1.3   Vector

Vector:我們可以將其理解為版本舊的、安全的、效率低的ArrayList,Vector中提供了一個獨特的取出方式,就是列舉Enumeration。此介面Enumeration的功能與 Iterator 介面的功能是類似的。

有興趣的可以自己瞭解:

public E elementAt(int index)

public E firstElement()

public E lastElement()

public void setElementAt(E obj, int index)

public void removeElementAt(int index)及其他刪除

public Enumeration<E> elements()

                                              Set介面

2.1     介面特點及主要子類

Set是不包含重複元素的集合介面,其子類均無法存放相同元素。

最常用的子類是無序不可重複的HashSet。其方法與Set介面方法相同。

HashSet下還有子類LinkedHashSet,可預測迭代順序的Set集合。

2.2     判斷元素唯一原理

2.2.1   ArrayList的contains方法判斷元素是否重複原理

ArrayList的contains方法會使用呼叫方法時,傳入的元素的equals方法依次與集合中的舊元素所比較,從而根據返回的布林值判斷是否有重複元素。此時,當ArrayList存放自定義型別時,由於自定義型別在未重寫equals方法前,判斷是否重複的依據是地址值,所以如果想根據內容判斷是否重複,需要重寫equals方法。

2.2.2   HashSet的add/contains等方法判斷元素是否重複原理

Set集合不能存放重複元素,其新增方法在新增時會判斷是否有重複元素,有重複不新增,沒重複則新增。

HashSet集合由於是無序的,其判斷唯一的依據是元素型別的hashCode與equals方法的返回結果。規則如下:

先判斷新元素與集合內已經有的舊元素的HashCode值

如果不同,判斷元素不同。

如果相同,再判斷equals比較結果,返回true則相同,返回false則仍然不同。

所以,使用HashSet儲存自定義型別,如果沒有重寫該類的hashCode與equals方法,則判斷重複時,使用的地址值,如果想通過內容比較元素是否相同,需要重寫該類的hashcode與equals方法。

hashCode方法重寫規則:將該物件的各個屬性值hashCode相加即是整個物件的HashCode值。如果是基本型別,類似int,則直接返回int值就是該屬性的hash值,如果是引用型別,類似String,就呼叫該成員變數的hashCode方法返回該成員變數hash值。這樣可以根據物件的內容返回hashCode值,從而可以根據hashCode判斷元素是否唯一。

但是由於在一些”碰巧的”情況下,可能出現內容不同但hashCode相同的情況,為了避免這些情況,我們加入一些干擾係數。

可是加入干擾係數後,仍會出現一些”碰巧”的情況,所以我們還要進行equals的二次判斷。

                                                     泛型

3.1     泛型概述

我們在集合中大量使用到了泛型,這裡來完整地介紹泛型知識。

泛型用來靈活地將資料型別應用到不同的類、方法、介面當中。將資料型別作為引數傳遞。

泛型是資料型別的一部分,我們將類名與泛型合併一起看做資料型別。

泛型的定義:定義泛型類可以預支地使用未知的型別。

泛型的使用:一般在建立物件時,將未知的型別確定具體的型別。當沒有指定泛型時,預設型別為Object型別。

3.2     泛型程式碼實現

泛型類:

                  定義:類名後<變數>  如:class A<E> {使用E完全類的定義}

                  使用:建立物件時確定型別

泛型方法:

                  定義:方法返回值前<變數> 如:public <T> void method(){使用T}

                  使用:呼叫方法時確定型別

泛型介面:

                  定義:介面後<變數> 如: interface B<T>{使用T完成介面定義}

                  使用:

1、定義類時確定型別

2、始終不確定型別,直到建立物件時確定型別

3.3     泛型優點及其他

3.3.1   泛型其他 

在JDK1.5出現前,使用Object代表任意型別,但在使用時,涉及到了強轉的麻煩。泛型替代了Object來代表任意型別。

泛型在編譯時會擦除:泛型僅用來在編譯期限制、方便程式設計師的操作,實際上真正編譯後的.class中是沒有泛型的,其中仍然使用的為Obejct類,通過類似多型的方式完成任意某個型別的指定。

泛型萬用字元?

定義:(檢視ArrayList的構造方法)無法在類中使用

            使用:呼叫方法時可以給予任意型別。參照Arraylist的構造方法

? extends E代表只要是E型別的子類即可

? super E代表只要是E型別的父類即可

3.3.2   泛型優點

提高程式的安全性

將執行期問題轉移到了編譯期

省去了型別強轉的麻煩

優化了程式設計