JAVA集合類——難得的總結

以下資料是在學習中總結出來的,希望對你有所幫助。如果需要請轉載,謝謝。

1. StringBuffer 線程安全,StringBuilder 線程不安全 效率稍高些

集(Set):集里的對象不按任何特定的方式排列,按索引值來操作數據,不能有重復的元素

列表(List):序列中的對象以線性方式存儲,按索引值來操作數據,可以有重復的元素

映射(Map):映射的每一項為“名稱—數值”對,名稱不可以重復,值可以重復,一個名稱對應一個唯一的值

顯示指定集合類型:不經歷裝箱過程。

【Java學習資料免費分享微信:tangniu520666,備注“4”。需要的可以留意一下】

Collection resulte = dao.retrieveByClause(TaskVO.class, sql);

轉換為數組時,明確指定返回數組的大小

return result.toArray(new TaskVO[result.size()]);

數組不能強制轉型:

String[] s= (String[])list.toArray();——錯誤

String[] s= (String[])list.toArray(new String[list.size()]);——正確

迭代器是按次序一個一個地獲取集合中所有的對象,是訪問集合中每個元素的標準機制。

迭代器的創建:Collection接口的iterator()方法返回一個Iterator

Iterator it=test.iterator(); //將test集合對象轉為迭代器

迭代器的常用方法:

hasNext() //判斷迭代器中是否有下一個元素

next() //返回迭代的下一個元素

Remove() //將迭代器新返回的元素刪除

The Iterator interface is shown below: public interface Iterator {

boolean hasNext();

Object next();

void remove(); // Optional

}

可以認為迭代器是指向兩個元素之間的位置.

在調用remove()方法的時候, 必須調用一次next()方法.

remove()方法實際上是刪除上一個返回的元素.

List常用方法:

void add(int index, Object element) :添加對象element到位置index上

boolean addAll(int index, Collection collection) :在index位置后添加容器collection中所有的元素

Object get(int index) :取出下標為index的位置的元素

int indexOf(Object element) :查找對象element 在List中第一次出現的位置

int lastIndexOf(Object element) :查找對象element 在List中最后出現的位置

Object remove(int index) :刪除index位置上的元素

ListIterator listIterator(int startIndex) :返回一個ListIterator 跌代器,開始位置為startIndex

List subList(int fromIndex, int toIndex) :返回一個子列表List ,元素存放為從 fromIndex 到toIndex之前的一個元素

ArrayList:我們可以將其看作是能夠自動增長容量的數組。

利用ArrayList的toArray()返回一個數組。

Arrays.asList()返回一個列表。

迭代器(Iterator) 給我們提供了一種通用的方式來訪問集合中的元素。

View方式:

一種是測量迭代元素的時間:

另一種測量使用toArray調用創建數組:

最后得到結果:

使用toArray調用中創建的數組迭代元素的速度要比使用iterator的速度大約快30%到60%。

但如果將使用toArray方法創建數組的時間開銷含在內。則使用iterator實際上要快10%到20%,所以我們盡量不要創建中間數組。而使用迭代的方式。

ArrayList自動擴充機制

實現機制:ArrayList.ensureCapacity(int minCapacity)

首先得到當前elementData 屬性的長度oldCapacity。

然后通過判斷oldCapacity和minCapacity參數誰大來決定是否需要擴容, 如果minCapacity大于

oldCapacity,那么我們就對當前的List對象進行擴容。

擴容的的策略為:取(oldCapacity * 3)/2 + 1和minCapacity之間更大的那個。然后使用數組拷

貝的方法,把以前存放的數據轉移到新的數組對象中

如果minCapacity不大于oldCapacity那么就不進行擴容。

LinkedList

LinkedList是采用雙向循環鏈表實現的。

利用LinkedList實現棧(stack)、隊列(queue)、雙向隊列(double-ended queue )。

它具有方法addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast()等。

用LinkedList實現隊列:

隊列(Queue)是限定所有的插入只能在表的一端進行,而所有的刪除都在表的另一端進行的線性表。

表中允許插入的一端稱為隊尾(Rear),允許刪除的一端稱為隊頭(Front)。

隊列的操作是按先進先出(FIFO)的原則進行的。

隊列的物理存儲可以用順序存儲結構,也可以用鏈式存儲結構。

用LinkedList實現棧:

棧(Stack)也是一種特殊的線性表,是一種后進先出(LIFO)的結構。

棧是限定僅在表尾進行插入和刪除運算的線性表,表尾稱為棧頂(top),表頭稱為棧底(bottom)。

棧的物理存儲可以用順序存儲結構,也可以用鏈式存儲結構。

ArrayList和LinkedList的比較:

ArrayList底層采用數組完成,而LinkedList則是以一般的雙向鏈表(double-linked list)完成,其內每個對象除了數據本身外,還有兩個 引用,分別指向前一個元素和后一個元素。

如果我們經常在List的開始處增加元素,或者在List中進行插入和刪除操作,我們應該使用LinkedList,否則的話,使用ArrayList將更加快速。

小結:

集合是一個保存其他對象的對象

Collection接口除了實現映射的集合類之外的所有集合類定義了一些方法

List集合類型描述了一種按位置存儲數據的對象,有序的。

ArrayList是一種在內存連續區域 中存儲數據的通用數組

編碼習慣:

面向接口的編程,盡可能降低代碼變化率:

List lst = new ArrayList();

盡量避免創建不必要的對象:vo應在if判斷成立時創建

TaskReportVO reportvos = new TaskReportVO();

if(i > 0){

lstAllVos.add(reportvos); }

盡量避免同時遍歷和刪除集合。因為這會改變集合的大小;

for( Iterator iter = ComList.iterator(); iter.hasNext();){

ComType com = iter.next();

if ( !com.getName().contains("abc")){

ComList.remove(com);}

}

推薦:

for( Iterator iter = ComList.iterator(); iter.hasNext();){

ComType com = iter.next();

if ( !com.getName().contains("abc")){

iter.remove(com); }

預估集合內持有對象的大小,不能持有大量對象,占據內存:

List lst = new ArrayList();

無限制的在lst中add element,勢必會造成lst占用內存過高。造成內存溢出

Map接口:

集合框架的第二類接口樹。

它提供了一組鍵值的映射。其中存儲的每個對象都有一個相應的關鍵字(key),關鍵字決定了對象在Map中的存儲位置。

關鍵字應該是唯一的,每個key 只能映射一個value。

常用方法:

Object put(Object key,Object value):用來存放一個鍵-值對Map中

Object remove(Object key):根據key(鍵),移除鍵-值對,并將值返回

void putAll(Map mapping) :將另外一個Map中的元素存入當前的Map中

void clear() :清空當前Map中的元素

Object get(Object key) :根據key(鍵)取得對應的值

boolean containsKey(Object key) :判斷Map中是否存在某鍵(key)

boolean containsValue(Object value):判斷Map中是否存在某值(value)

public Set keySet() :返回所有的鍵(key),并使用Set容器存放

public Collection values() :返回所有的值(Value),并使用Collection存放

public Set entrySet() :返回一個實現 Map.Entry 接口的元素 Set

HashMap:

Map 主要用于存儲鍵(key)值(value)對,根據鍵得到值,因此鍵不允許重復,但允許值重復。

HashMap 是一個最常用的Map,它根據鍵的HashCode 值存儲數據,根據鍵可以直接獲取它的值,具有很快的訪問速度。

HashMap最多只允許一條記錄的鍵為Null;允許多條記錄的值為 Null;

HashMap不支持線程的同步,即任一時刻可以有多個線程同時寫HashMap;可能會導致數據的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力。

HashMap實現原理---散列

Hash哈希算法的意義在于提供了一種快速存取數據的方法,它用一種算法建立鍵值與真實值之間的對應關系。散列表又稱為哈希表。散列表算法的基本思想是:以結點的關鍵字為自變量,通過一定的函數關系(散列函數)計算出對應的函數值,以這個值作為該結點存儲在散列表中地址。

當散列表中的元素存放太滿,就必須進行再散列,將產生一個新的散列表,所有元素存放到新的散列表中,原先的散列表將被刪除。在Java語言中,通過負載因子(load factor)來決定何時對散列表進行再散列。例如:如果負載因子0.75,當散列表中已經有75%位置已經放滿,那么將進行再散列。

負載因子越高(越接近1.0),內存的使用效率越高,元素的尋找時間越長。負載因子越低(越接近0.0),元素的尋找時間越短,內存浪費越多。

何時需重寫equals?

當一個類有自己特有的“邏輯相等”概念(不同于對象身份的概念);

Object類僅僅提供了一個對引用的比較,如果兩個引用不是同一個那就返回false,這是無法滿足大多數對象比較的需要的,所以要覆蓋;

使用==操作符檢查實參是否為指向對象的引用”

使用instanceof操作符檢查實參是否為正確的類型

把實參轉換到正確的類型;

對于該類中每一個“關鍵”域,檢查實參中的域與當前對象中對應的域值是否匹 配。對于既不是float也不是double類型的基本類型的域,可以使用==操作符 進行比較;對于對象引用類型的域,可以遞歸地調用所引用的對象的equals方法,對于float和double類型的域,先轉換成int或long類型的值,然后使用==操作符比較;

當你編寫完成了equals方法之后,應該問自己三個問題:它是否是對稱的、傳 遞的、一致的? 如果答案是否定的,那么請找到 這些特性未能滿足的原因,再修改equals方法的代碼

equals()和hashCode()同時覆寫

尤其強調當一個對象被當作鍵值(或索引)來使用的時候要重寫這兩個方法;

覆寫equals后,兩個不同實例可能在邏輯上相等,但是根據Object.hashCode方法卻產生不同的散列碼,違反“相等的對象必須具有相等的散列碼”。

導致,當你用其中的一個作為鍵保存到hashMap、hasoTable或hashSet中,再以“相等的”找另 一個作為鍵值去查找他們的時候,則根本找不到

不同類型的hashCode取值

如果該域是布爾型的,計算(f?0:1)

如果是char,short,byte或int,計算(int)f

如果是long類型,計算(int)(f^(f>>>32))

如果是float類型,計算Float.floatToIntBits(f)

如果是double類型,計算Dobule.doubleToLongBits(f)

如果該域是一個對象引用,遞歸調用hashCode

如果該域是一個數組,則把每個元素當做單獨的域來處理,對每個重要的元素計算一個散列碼,

比較:

HashMap的存入順序和輸出順序無關。

LinkedHashMap 則保留了鍵值對的存入順序。

TreeMap則是對Map中的元素進行排序。

因為HashMap和LinkedHashMap 存儲數據的速度比直接使用TreeMap 要快,存取效率要高。

當完成了所有的元素的存放后,我們再對整個的Map中的元素進行排序。這樣可以提高整個程序的運行的效率,縮短執行時間。

注意:TreeMap中是根據鍵(Key)進行排序的。而如果我們要使用TreeMap來進行正常的排序的話,Key 中存放的對象必須實現Comparable 接口。

Set:

擴展Collection接口

不允許重復元素

對 add()、equals() 和 hashCode() 方法添加了限制

HashSet和TreeSet是Set的實現

Set—》hashSet linkedHashSet

SortedSet —》 TreeSet

HashSet常用方法:

public boolean contains(Object o) :如果set包含指定元素,返回true

public Iterator iterator()返回set中元素的迭代器

public Object[] toArray() :返回包含set中所有元素的數組public Object[] toArray(Object[] a) :返回包含set中所有元素的數組,返回數組的運行時類型是指定數組的運行時類型

public boolean add(Object o) :如果set中不存在指定元素,則向set加入

public boolean remove(Object o) :如果set中存在指定元素,則從set中刪除

public boolean removeAll(Collection c) :如果set包含指定集合,則從set中刪除指定集合的所有元素

public boolean containsAll(Collection c) :如果set包含指定集合的所有元素,返回true。如果指定集合也是一個set,只有是當前set的子集時,方法返回true

實現Set接口的HashSet,依靠HashMap來實現的。

我們應該為要存放到散列表的各個對象定義hashCode()和equals()。

如何達到不能存在重復元素的目的?

“鍵”就是我們要存入的對象,“值”則是一個常量。這樣可以確保,我們所需要的存儲的信息

之是“鍵”。而“鍵”在Map中是不能重復的,這就保證了我們存入Set中的所有的元素都不重復。

HashSet如何過濾重復元素

調用元素HashCode獲得哈希碼--》判斷哈希碼是否相等,不相等則錄入

---》相等則判斷equals()后是否相等,不相等在進行 hashcode錄入,相等不錄入

TreeSet:

TreeSet是依靠TreeMap來實現的。

TreeSet是一個有序集合,TreeSet中元素將按照升序排列,缺省是按照自然順序進行排列,意味著TreeSet中元素要實現Comparable接口

我們可以在構造TreeSet對象時,傳遞實現了Comparator接口的比較器對象。

幾種Set的比較:

HashSet外部無序地遍歷成員。

成員可為任意Object子類的對象,但如果覆蓋了equals方法,同

時注意修改hashCode方法。

TreeSet外部有序地遍歷成員;

附加實現了SortedSet, 支持子集等要求順序的操作

成員要求實現Comparable接口,或者使用Comparator構造

TreeSet。成員一般為同一類型。

LinkedHashSet外部按成員的插入順序遍歷成員

成員與HashSet成員類似

HashSet是基于Hash算法實現的,其性能通常都優于TreeSet。我們通常都應該使用HashSet,在我們需要排序的功能時,我們才使用TreeSet。

HashSet的元素存放順序和我們添加進去時候的順序沒有任何關系,而LinkedHashSet 則保持元素的添加順序。TreeSet則是對我們的Set中的元素進行排序存放。

一般來說,當您要從集合中以有序的方式抽取元素時,TreeSet 實現就會有用處。為了能順利進行,添加到 TreeSet 的元素必須是可排序的。 而您同樣需要對添加到TreeSet中的類對象實現 Comparable 接口的支持。一般說來,先把元素添加到 HashSet,再把集合轉換為 TreeSet 來進行有序遍歷會更快。

Comparable和Comparator

Comparable 接口以提供自然排序順序。

對于那些沒有自然順序的類、或者當您想要一個不同于自然順序的順序時,您可以實現

Comparator 接口來定義您自己的排序函數。可以將Comparator傳遞給Collections.sort或Arrays.sort。

Comparator接口

當一個類并未實現Comparable,或者不喜歡缺省的Comaparable行為。可以實現Comparator接口

直接實現Comparator的compare接口完成自定義比較類。

例:Arrays.sort(results, new Comparator() 數組排序 RepDataQueryExecutor

例:Collections.sort(lst,new Comparator()

本文是在學習中的總結,歡迎轉載但請注明出處:http://blog.csdn.net/pistolove/article/details/41346969

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,739評論 18 399
  • 3.3 集合 一方面, 面向對象語言對事物的體現都是以對象的形式,為了方便對多個對象的操作,就要對對象進行存儲。另...
    閆子揚閱讀 744評論 0 1
  • 集合類簡介 為什么出現集合類?面向對象語言對事物的體現都是以對象的形式,所以為了方便對多個對象的操作,就要對對象進...
    阿敏其人閱讀 1,439評論 0 7
  • Java集合框架 Java平臺提供了一個全新的集合框架。“集合框架”主要由一組用來操作對象的接口組成。不同接口描述...
    小石38閱讀 366評論 0 0
  • 早上出門,本來只有薄薄的雪帶著明媚的陽光,卻怎么也阻擋不了寒風流進我的全身。 下班路上,地面淺淺的水洼,沒有...
    璇凝兒閱讀 173評論 0 0