Java類集

1.類集基礎

(1)所謂的類集就是一個動態的對象數組,是對一些實現好的數據結構進行了包裝,最重要的是類集框架本身不受數組長度的限制。
(2)在整個Java類集中最常用類集接口是:
這裏寫圖片描述
注:所有的類集操作都放在java.util包中。
接口之間其實是存在繼承關係的,如下所示:
Collection接口:
這裏寫圖片描述
Map接口:
這裏寫圖片描述
注:SortedXx定義的接口都屬於排序接口,如SortedSet、SortedMap。

2.Collection接口

(1)Collection接口的定義
定義:

public interface Collection<E> extends Iterable <E>

注:JDK1.5之前的類集框架中可以存放任意的對象到集合中,這樣一來在操作時就可能出現因爲類型不統一而造成的ClassCastException異常。故在JDK1.5之後爲了保證類集中所有元素的類型一致,將類集框架進行了升級,加入了泛型,這樣就可以保證一個集合中的全部元素的類型都是統一的。
Collection接口是單值存放的最大父接口,可以向其中保存多個單值(單個的對象)數據。

Collection接口的方法定義如下:
這裏寫圖片描述

在一般的開發中,往往很少直接使用Collecion接口進行開發,基本上都是使用其子接口。子接口主要有List、Set、Queue和SortSet。這是爲了讓程序的開發及使用更加明確。

(2)Collection子接口的定義
主要子接口如下:
List:可以存放重複的內容。
Set:不能存放重複的內容,所有的重複內容靠hashCode()和equals()兩個方法區分。
Queue:隊列接口。
SortedSet:可以對集合中的數據進行排序。

3.List接口

(1)List接口的定義
List接口是Collection的子接口,其中可以保存各個重複的內容。
定義:

public interface List<E> extends Collection<E>

List接口大量擴充了Collection接口,擁有比Collecion接口中更多的方法定義。
List中對Collecion接口的擴展方法如下:
這裏寫圖片描述
要想使用此接口,則需要通過其子類進行實例化。

(2)List接口的常用子類
List接口的常用子類是ArrayList、Vector、LinkedList。
1)ArrayList子類
定義:

public class ArrayList<E> extends AbstractList<E> implements List<E>,RandomAccess,Cloneable,Serializable

從中可以看出ArrayList子類繼承自AbstractList類。
AbstractList類的定義:

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>

此類實現了List接口,所以可以直接通過ArrayList爲List接口實例化。
①向集合中增加元素
直接使用Collection接口中定義的方法:

增加一個元素:public boolean add(E o)
增加一組元素:public boolean addAll(Collection<?extends E> c)

也可以使用List接口中定義的方法:

在指定位置處添加一組元素:public void add(int index,E element)

②刪除元素
Collection定義的方法:

每次刪除一個對象:public boolean remove(Object o)
每次刪除一組對象:public boolean removeAll(Collection<?> c)

List擴展的方法:

刪除指定位置的元素:public E remove(int index)

③輸出List中的內容
在Collection接口中定義了取得全部數據長度的方法size(),而在List接口中存在取得集合中指定位置元素的操作get(int index),使用這兩個方法即可輸出集合中的全部內容。

for(int i=0;i<allList.size();i++){
    System.out.print(allList.get(i)+”、”);
}

④將集合變成對象數組
在Collecion中定義了toArray()方法,此方法可以將集合變爲對象數組,但是由於在類集聲明時已經通過了泛型指定了集合中的元素類型,所以在接收時要使用泛型指定的類型。
⑤集合的其他操作
在List中還存在截取集合、查找元素位置、判斷元素是否存在、集合是否爲空等操作。

2)Vector子類
歷史比較老,相對於ArrayList子類來說。
定義:

public class Vector<E> extends AbstractList<E> implements List<E>,RandomAccess,Cloneable,Serializable

3)ArrayList與Vector的區別
這裏寫圖片描述

(2)LinkedList子類與Queue接口
LinkedList是一個鏈表的操作類,即Java中已經爲開發者提供好了一個鏈表程序,開發者直接使用即可,無須重新開發。
定義:

public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>,Queue<E>,Cloneable,Serialzable

此類不僅實現了List接口,同時也實現了Queue接口。Queue表示的是隊列操作接口(先進先出)。
Queue接口的定義:

public interface Queue<E> extends Collection<E>

Queue接口也可以增加元素並輸出,方法如下:
這裏寫圖片描述
在LinkedList類中除了實現Queue接口中的方法外,還提供了操作鏈表的方法
這裏寫圖片描述
①在鏈表的開頭和結尾增加數據
爲了達到操作鏈表的母的,必須直接使用LinkedList類。
②找到鏈表頭
常用方法:

找到表頭:public E element();
找到不刪除表頭:public E peek();
找到並刪除表頭:public E poll();

③以先進先出的方式取出全部的數據
在LinkedList類中存在poll()方法,通過循環此操作,就可以把內容全部取出(以先進先出的方式)。

4.Set接口

(1)Set接口的定義
Set接口也是Collection接口的子接口,但是與Collection或List接口不同的是,Set接口中不能加入重複的元素。
Set接口定義:
public interface Set extends Collection
Set接口的主要方法與Collection接口的主要方法是一致的,也就是說Set接口並沒有對Collection接口進行擴充,只是比Collection接口的要求更加嚴格了,不能增加重複元素。
Set接口的實例不能像List接口那樣可以進行雙向輸出,因爲此接口沒有提供像List接口定義的get(int index)方法。
(2)Set接口的常用子類
Set接口的常用子類是HashSet、TreeSet。
1)HashSet(散列存放)
HashSet是Set接口的一個子類,主要特點是:裏面不能存放重複元素,而且採用散列的存儲方式,所以沒有順序。
注:其中對於重複元素只能增加一次,而且程序運行時向集合中加入元素的順序並不是集合中的順序。

2)TreeSet(有序的存放)
定義:
public class TreeSet extends AbstractSet implements SortedSet,Cloneable,Serializable
TreeSet也是繼承了AbstractSet類
此類的定義如下:
public abstract class AbstractSet extends AbstractCollection implements Set
注:在TreeSet中即使插入數據是沒有順序的,輸出之後的數據仍是有序的。
3)關於TreeSet的排序說明
如果自定義一個類,需要爲其指定好排序規則,且TreeSet中的每個對象所在的類都必須實現Comparable即可纔可以正常使用。
4)關於重複元素的說明
①一個好的類應該覆寫Object類中的equals()、hashCode()、toString()三個方法,實際上在String中已經全部覆寫完成。(區分同一對象)
②Set接口依靠hashCode()和equals()完成重複元素的判斷,在Map接口中同樣也是。
③TreeSet接口依靠Comparable接口完成排序操作。

5.SortSet接口

TreeSet接口實現了SortSet接口,此接口主要用於排序操作,即實現此接口的子類都屬於排序的子類。
定義:
public interface SortedSet extends Set
此類也繼承了Set接口,其中SortedSet接口的定義:
這裏寫圖片描述

6.集合的輸出

如果要輸出Collection、Set集合中的內容,可以將其轉換爲對象數組輸出,而使用List則可以直接通過get()方法輸出,但是這些都不是集合的標準輸出方式。
在類集中提供了一下四種常見的輸出方式:
①Iterator:迭代輸出,是使用最多的輸出方式。
②ListIterator:是Iterator的子接口,專門用於輸出List中的內容。
③Enumeration:是一箇舊的接口,與Iterator類似。
④foreach:JDK1.5之後提供額的新功能,可以輸出數組或集合。(很簡便)

(1)迭代輸出:Iterator
思路:只要是碰到了集合輸出的操作,就一定使用Iterator接口。
Iterator是專門的迭代輸出接口,所謂的迭代輸出就是將元素一個個進行判斷,判斷其是否有內容,如果有內容則把內容輸出。
定義:public interface Iterface<E>

常用方法:
public boolean hasNext() 判斷是否有下一個值
public E next() 取出當前元素
public void remove() 移除當前元素

①輸出Collection中的全部內容
Iterato是一個接口,可以直接使用Collection接口中定義的iterator()方法爲其實例化。
Iterator iter=all.iterator();
while(iter.hasNextI()){
System.out.println(iter.next()+”、”);
}
②使用Iterator刪除指定內容(最好不要刪除)
直接使用remove()方法即可。
③迭代輸出時刪除元素的注意點
正常情況下,一個集合要把內容交給Iterator輸出,但是集合操作時也存在一個remove()方法,如果在使用Iterator輸出時由集合對象調用了自身的刪除方法,則會出現運行時的錯誤。

注:Iterator接口的功能是從前向後輸出,是單向輸出。

(2)雙向迭代輸出:ListIterator
如果要想實現由後向前或是由前向後的雙向輸出,則必須使用Iterator的子接口-ListIterator。
定義:public interface ListIterator<E> extends Iterator<E>

與Iterator接口不同的是,ListIterator接口只能通過List接口實例化,即只能輸出List接口中的內容。
①進行雙向迭代
使用ListIterator接口中的hasPrevious()方法由後向前判斷,並使用previous()方法取出前一個元素。
注:由後向前輸出時必須先由前向後輸出。
②增加及刪除元素
使用add()或set()方法可以增加或替換集合中的元素,但是這樣的操作並不建議使用。

(3)新支持的:foreach
格式:

for(類 對象:集合){
    集合操作;
}

注:雖然foreach功能強大,但仍建議使用Iterator接口完成輸出功能。

(4)廢棄的接口:Enumeration
定義:public interface Enumeration<E>
要想使用此接口只能通過Vector類,Vector類定義如下方法爲Enumeration接口實例化:
public Enumeration<E> elements()

注:雖然Enumeration接口是很老的接口,但是在某些古老的系統或類庫的方法中仍在使用Enumeration接口。

7.Map接口

(1)Map接口簡介
與Collection接口相關的幾個接口均屬於單值操作,即每次只能操作一個對象,而Map接口與它們不同的是,每次操作的是一對對象,即二元偶對象,Map接口中每個元素都使用”key->value”的形式存儲在集合中。
定義:public interface Map

①HashMap:無序存放的,是新的操作類,key不允許重複。
②Hashtable:無序存放的,是舊的操作類,key不允許重複。
③TreeMap:可以排序的Map集合,按集合中的key排序,key不允許重複。
④WeakHashMap:弱引用的Map集合,當集合中的某些內容不再使用時清除掉無用的數據,使用gc進行回收。
⑤IdentityHashMap:key可以重複的Map集合。

1)HashMap(新的子類)
HashMap本身是Map的子類,直接使用此類爲Map接口實例化即可。
HashMap類的定義:

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>,Cloneable,Serializable

HashMap是AbstractMap類的子類,其定義如下:

public abstract class AbstractMap<K,V> extends Object implements Map<K,V>

HashMap相關操作
①向集合中增加和取出內容
在Map接口中使用put(K key,V value)方法可以向集合中增加內容,之後可以通過get(Object key)方法根據key找出其對應的value。
②判斷指定的key或value是否存在
如果要判斷某一個指定的key或value是否存在,可以使用Map接口中提供的containsKey(Object key)和containValue(Object value)兩個方法,前者是判斷Map集合是否存在指定的key,後者是判斷Map集合是否存在指定的value。
③輸出全部的key
在Map接口中提供了一個叫做keySet()的方法,可以將一個Map接口中的全部key變爲一個Set集合,一旦有了Set接口實例,就可以直接使用Iterator接口進行輸出。
注:接收的Set集合中指定的泛型要和Map中的key的泛型類型保持一致。
④輸出全部的value
如果要輸出全部的value,則使用values()方法,此方法的返回類型是Collection。

2)Hashtable(舊的子類)
Hashtable也是Map接口的一個子類,是舊的操作類,使用上和之前並沒有太大區別。

HashMap與Hashtable的區別
這裏寫圖片描述
3)TreeMap
TreeMap子類的特點是可以按key排序。
注:使用自定義類作爲key時類需要實現Comparable接口,否則會出現類轉換異常。

4)弱引用類:WeakHashMap
以上的Map接口的子類中的數據都是使用強引用保存的,即裏面的內容不管是否使用都始終在集合中保留,如果希望集合自動清理暫時不用的數據就使用WeakHashMap類。這樣,當進行垃圾收集時就會釋放掉集合中的垃圾信息。
定義:

public class WeakHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>

關於對象的引用強度談論(在java.lang.ref包中可觀察)

強引用:當內存不足時,JVM寧可出現OutOfMemoryError錯誤而使程序停止,也不好回收此對象來釋放空間。
軟引用:當內存不足時,會回收這些對象的內存,用來實現內存敏感的高速緩存。
弱引用:無論內存是否緊張,被垃圾回收器發現立即回收。
虛引用:和沒有任何引用一樣。

5)關於Map接口使用的注意事項
①不能直接使用迭代輸出Map中的全部內容
對於Map接口來說,其本身是不能直接使用迭代進行輸出的,因爲Map接口中的每個位置存放的是一對值(key->value),而Iterator中每次只能找到一個值。所以如果非要使用使用迭代輸出,則必須按以下步驟完成。
A.將Map接口的實例通過entrySet()方法變爲Set接口對象。
B.通過Set接口爲Iterator實例化
C.通過Iterator迭代輸出,每個內容都是Map.Entry的對象。
D.通過Map.Entry進行key->value的分離。
注:Map集合的內容在開發中基本上作爲查詢的應用較多,全部輸的操作較少。而Collection接口在開發中的主要作用就是用來傳遞內容及輸出的。

②直接使用非系統類作爲key
使用一個字符串作爲key,用一個Person對象表示value是可以的。
但是反過來,將一個Person對象作爲key,一個字符串作爲value卻會出現問題。
如果要想使用一個自定義的對象表示Map對象的key,則對象所在類中一定要覆寫equals()和hashCode()方法,否則無法通過匿名對象找到對應的value。

6)IdentityHashMap(key可以重複)
前面的Map的子類中的key值是不能重複的,如果重複則肯定會覆蓋之前的內容。
而在IdentityHashMap中的key是可以重複的,只要兩個對象的地址不相等即可。

8.SortMap接口

SortMap接口是排序接口,只要實現了此接口的子類,都屬於排序的子類,TreeMap也是此接口一個子類。
定義:pubic interface SortMap

9.集合工具類:Collections

定義:public class Collections extends Object

Collections類與Collection接口的關係:
Collections類與Colleecion接口沒有直接的關係,但是與集合中的各個接口都有操作方法的支持。

常用方法:
這裏寫圖片描述

(1)返回不可變的集合
Collections類中的可以返回空的List、Set、Map集合,但是通過這種方式返回的對象是無法進行增加數據的,因爲在這些操作中並沒有實現add()方法。
(2)爲集合增加內容
使用addAll()方法可以爲一個集合增加內容。此方法可以接收可變參數。
(3)反正集合中的內容
直接使用Collections工具類中的reverse()方法即可將集合類中的內容反轉保存。
(4)檢索內容
直接通過Collections工具類中的binarySearch()方法即可完成內容的檢索,檢索之後會返回內容的位置。
(5)替換集合中的內容
Collections類中也提供了replaceAll()方法,可以替換一個集合中的指定內容。
(6)集合排序
可以通過Collection類中的sort()方法對一個集合進行排序操作,但是要求集合中每個對象所在的類必須實現Comparable接口。
(7)交換指定位置的內容
直接使用swap()方法可以把集合中兩個位置的內容進行交換。

10.其他集合類

(1)Stack類
棧是採用先進後出的數據存儲方式,每一個棧都包含一個棧頂,每次出棧都是將棧頂的數據取出。注:瀏覽器上的後退按鈕其實就是棧的一個應用。
在Java中使用Stack類進行棧的操作,Stack類是Vector的子類。
定義:public class Stack<E> extends Vector<E>
注:先進去的內容最後才取出,而且如果棧已經空,則無法再彈出,會出現空棧異常。
(2)屬性類:Properties
在一個屬性文件中保存了多個屬性,每一個屬性就是直接用字符串表示出來的”key=value”對。
Properties類本身是Hashtable類的子類,既然是子類,則肯定也是按照key和value的形式存放數據的。
定義:public class Properties extends Hashtable

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章