Java語法總結--Java集合類


 

這一節我們來總結一下Java集合類。

Java集合總結
  繼承與Collection接口的–List接口
    List接口本身的特點
    常見的繼承List接口的實用類
    實用類對比
  繼承與Collection接口的–Set接口
    Set接口本身的特點
    常見的繼承Set接口的實用類
    實用類對比
  繼承與Collection接口的–Queue接口
    Queue接口本身的特點
    常見的繼承Queue接口的實用類
  特例獨立的–Map接口
    Map接口本身的特點
    常見的繼承Map接口的實用類
    實用類對比
  操作集合的工具類:Collections

Java集合總結

  Java集合是每個Java程序員在日常開發中都會使用到,而且有時候使用得好的話,能事半功倍。細數Java集合,其實比較常見的就是List、Set、Map和Queue,在這四者之中,除了Map之外,其他三個接口都繼承於Collection。 
  在這里,首先我們要明確的是,List、Set、Map和Queue其實只是以接口的形式存在着的,所以在日常的程序開發中,請不要出現說想要直接初始化它們的想法和做法,雖然筆者也曾經犯過這樣子的錯誤。

繼承與Collection接口的–List接口

List接口本身的特點

  List接口在Java的集合類中充當的是一個元素有序、元素可重復的集合角色。List繼承於Collection集合,故其擁有了Collection集合的全部方法,同時,List集合也擁有屬於自己的方法:用來實現根據元素索引來操作集合元素的作用。通過List集合的源碼(JDK1.7)我們簡單地看看List集合包含的方法:

package java.util; 
public interface List extends Collection {

int size();                            //集合元素的數量
boolean contains(Object o);            //是否包含某變量,包含返回ture
Iterator<E> iterator();
Object[] toArray();                    //將集合轉化為一個數組,所有的集合元素變成相應的數組元素
<T> T[] toArray(T[] a);                //將集合轉化為一個類型T數組
boolean add(E e);                      //增加元素,成功返回true
boolean remove(Object o);              //移除元素,成功返回true
boolean containsAll(Collection<?> c);             //是否包含集合c中的全部元素,若是返回true
boolean addAll(Collection<? extends E> c);        //添加整個集合c中全部元素,
boolean addAll(int index, Collection<? extends E> c);
boolean removeAll(Collection<?> c);               //移除該List集合中包含的c中的全部元素
boolean retainAll(Collection<?> c);               //是否包含c集合中的元素,包含返回ture
void clear();                                     //清空集合
boolean equals(Object o);
int hashCode();
E get(int index);                                 //根據index取元素值
E set(int index, E element);                      //根據index把List該元素重新復制element
void add(int index, E element);                   //根據index添加新元素element
E remove(int index);
int indexOf(Object o);                            //返回對象o在List集合中第一次出現的位置索引
int lastIndexOf(Object o);                        //返回對象o在List集合中最后一次出現的位置索引
ListIterator<E> listIterator();
ListIterator<E> listIterator(int index);
List<E> subList(int fromIndex, int toIndex);      //截斷集合

}

 

常見的繼承List接口的實用類

  • ArrayList 
      ArrayList是基於數組實現的List類,故其封裝了一個動態的、允許再分配的Object[]數組,ArrayList用initialCapacity參數來設置該數組的長度,當長度超過預設值后,ArrayList會動態增加。 
    ArrayList類是線程不安全的,如果要保證該集合的同步性,必須在程序中手動保證。 
    值得注意的是:雖說與以鏈表形式建立的LinkedList相比,ArrayList()的插入和修改速度較慢,但那個也是建立在數據量較大的情況下的,在數據量較小的情況下,ArrayList()不一定比LinkedList()方法要慢。另外,ArrayList在末尾插入和刪除數據的話,速度反而比LinkedList要快
  • LinkedList 
      LinkedList(): 在實現中采用鏈表數據結構。插入和刪除速度快,訪問速度慢。 
    因為除了繼承List接口外,LinkedList接口也繼承了Deque接口,故也可以當作“棧”和隊列(雙向隊列)來使用。因此LinkList接口也會多出一些Deque接口方面的方法,如offer()(將元素接到隊列的尾部)、push()或offerFirst()(將元素加入棧的頂部)、peek()或peekFirst()(訪問但是不刪除棧頂元素)、pop()或者pollLast()(將棧頂元素彈出棧)等方法。
  • Vector 
      Vector與ArrayList十分地相像,都是基於數組實現的List類,其也是封裝了一個動態分配的Object[]數組,也可以使用initialCapacity參數來設置該數組的長度。 
    Vector是線程安全的,但是也因此Vector的性能很差。
  • Stack 
      Stack是繼承與Vector的子類,它主要用來模擬”棧“,因此也具備了peek()、pop()、push()等主要用於棧操作的方法。 
      由於Stack是一個比較古老的Java集合類,它同樣是線程安全的,但也因此暴露出了性能較差的缺點,如果程序中要使用棧這樣的數據結構的話,可以試一試ArrayDeque,該類也是List的實現類,但和LinkedList一樣也繼承了Deque接口。

實用類對比

分類 ArrayList LinkedList Vector Stack
實現形式 動態數組 鏈表 動態數組 動態數組
線程安全性 線程不安全 線程不安全 線程安全 線程安全
優點 性能較高,隨機訪問速度快 插入和刪除速度快 線程安全 線程安全
缺點 插入與刪除元素的速度慢 隨機訪問速度訪問速度慢 性能較差 性能較差

使用List集合有以下建議: 
1、遍歷集合元素。ArrayList和Vector使用get()方法來獲取遍歷元素,LinkedList應該采用迭代器來遍歷集合元素。 
2、插入和刪除。當這類操作較多的時候,優先考慮使用LinkedList。 
3、多線程。當需要使用到多線程的ArrayList時,可以使用Collections將該集合類包裝成線程安全的集合。

繼承與Collection接口的–Set接口

Set接口本身的特點

  Set代表的是無序的、不可重復的集合。因此在Set集合中加入數據元素時,Set集合通常不用記住元素的添加順序。不可重復則是說當將兩個相同的元素加入到一個Set集合中,則添加操作失敗,add()方法返回false,且新元素不會被添加。 

public interface Set extends Collection {

int size();                             //集合元素的數量

boolean isEmpty();                      //判斷集合是否為空

boolean contains(Object o);              //是否包含某變量,包含返回ture

Iterator<E> iterator();

Object[] toArray();

<T> T[] toArray(T[] a);

boolean add(E e);

boolean remove(Object o);

boolean containsAll(Collection<?> c);              //是否包含c集合中的元素,包含返回ture

boolean addAll(Collection<? extends E> c);         //添加包含c集合中所有的元素,包含返回ture

boolean retainAll(Collection<?> c);                 

boolean removeAll(Collection<?> c);

void clear();

boolean equals(Object o);

int hashCode();

}

 

常見的繼承Set接口的實用類

  • HashSet 
    HashSet按照Hash算法來存儲集合中的元素,因此具有良好的存取和查找功能。 
    HashSet有三個特點:與TreeSet不同,HashSet是無序的;不是線程同步;集合元素可以是null值。 
    HashSet集合的存儲過程:當向HashSet集合中存入一個元素時,HashSet會調用該對象的hashCode()方法來得到該對象的hashCode值,然后根據該值決定該對象在HashSet中的存儲位置。如果有兩個元素通過equals()方法返回true,但他們的hashCode()方法返回值不相等,HashSet也會將其存儲在不同的位置。也就是說:HashSet的添加元素判斷標准是:兩個對象通過equals()方法比較相等,並且兩個對象的hashCode()方法返回值也相等。
  • LinkedHashSet 
    LinkedHashSet是繼承於HashSet的子類。 
    但是與父類不同的是,LinkedHashSet用以鏈表的形式來維護元素的次序,也就是說:LinkedHashSet是有序的。遍歷該集合時輸出順序為添加順序。
  • TreeSet 
    TreeSet是SortedSet接口的實現類,所以TreeSet可以確保集合元素處於排序狀態。TreeSet使用紅黑樹來維護集合元素的次序。如果實現comparator()方法,可以實現定制排序。如果采用自然排序,則返回null。 
    TreeSet集合的特有方法:first()、last()、lower(Object e)(返回指定元素之前的元素)、higher(Object e)(返回指定元素之后的元素)等等。 
    下面我們說一說TreeSet的定制排序和自然排序: 
    1、 定制排序 
    通過Comparator接口的幫助,實現降序排序。 
    2、 自然排序 
    TreeSet通過CompareTo(Object obj)比較元素之間的大小關系,將集合元素按升序排列。實現元素必須實現Comparable元素,而且在比較的時候如果出現不同類型時要轉換類型后比較。
  • EnumSet 
    EnumSet是專門為枚舉類設計的集合類,EnumSet中的所有元素都必須是指定枚舉類型的枚舉值,該枚舉類型在創建EnumSet時顯式或隱式地指定。 
    EnumSet在內部以位向量的形式存儲,十分緊湊、高效,因此EnumSet對象占用內存很小,且運行效率很高。但是該集合元素中不允許加入null元素。

實用類對比

分類 HashSet LinkedHashSet TreeSet EnumSet
實現形式 Hash存儲 鏈表+Hash存儲 紅黑樹 枚舉類型(位向量)
線程安全性 線程不安全 線程不安全 線程不安全 線程不安全
優點 插入和刪除速度快 集合元素有序,插入和刪除速度較快 集合元素有序,插入和刪除速度較快 批量操作速度較快,性能最好
缺點 集合元素無序 (鏈表)性能較差 (紅黑樹)性能較差 只能用來存儲枚舉類型

繼承與Collection接口的–Queue接口

Queue接口本身的特點

Queue用來模擬隊列這種數據結構,故其擁有add()、element()、offer()、peek()、poll()、remove()等方法。 

package java.util; 
public interface Queue extends Collection {

boolean add(E e);         //在隊尾增加元素e

boolean offer(E e);       //在隊尾增加元素e

E remove();               //獲取隊列頭部的元素,並移除該元素

E poll();                 //獲取隊列頭部的元素,並移除該元素

E element();              //獲取隊列頭部的元素,但不移除該元素

E peek();                 //獲取隊列頭部的元素,但不移除該元素

}

 

常見的繼承Queue接口的實用類

  • PriorityQueue 
    PriorityQueue是Queue的標准隊列實現類。PriorityQueue不是按照加入隊列的順序進行排列的,而是根據隊列大小進行重新排序的(升序),這一點要特別注意的。 
    PriorityQueue中不允許插入null元素,它也有兩種排序方式:自然排序(實現Comparable接口,且為同一個類比較)和定制排序(建立對象時傳入一個Comparator對象)。這個部分和TreeSet的要求基本一致。
  • Deque–ArrayDeque 
    首先要說明的是:Deque是Queue的子接口,代表的是雙向鏈表,故該接口中也定義了一些方法來從兩端來操作隊列的數據。 
    ArrayDeque:是一個基於數組實現的雙端隊列,它與ArratList的實現體制很相像,都會采用了動態可再分配的數組來存儲集合元素。但是其在用途上主要是被當作”棧“來使用。
  • Deque–LinkedList 
    LinkedList在上述已表述過。與ArrayDeque不同的是,LinkedList是使用鏈表實現的。

特例獨立的–Map接口

Map接口本身的特點

  Map與上述三個接口不同的是,該接口無法繼承於Collection接口,主要原因還是因為Map是用來存儲具有映射關系的數據,所以Map中保存着兩組值。一組值用來保存Map中的Key,另外一組用來保存Map里的value。值得注意的是:Map中的key不能重復。判斷標准是同一個Map對象的任何兩個key通過equals方法比較總是返回false。

package java.util;

public interface Map {

int size();

boolean isEmpty();

boolean containsKey(Object key);              //是否包含key值,如果是返回true

boolean containsValue(Object value);          //是否包含value值,如果是返回true

V get(Object key);                            //根據key值獲取相應的value值

V remove(Object key);                         //根據key值從集合中移除相應的value值

void putAll(Map<? extends K, ? extends V> m); //將指定的m中的key-value復制到該集合中

void clear();

Set<K> keySet();                              //返回該Map中所有key組成Set集合

Collection<V> values();                       //返回該Map中所有的value組成的Collection

Set<Map.Entry<K, V>> entrySet();              //返回Map中包含的key-value對所組成的Set組合,每個集合元素都是Map.Entry對象。

interface Entry<K,V> {

    K getKey();                               //返回該Entry里面包含的key值

    V getValue();                             //返回該Entry里面包含的value值

    V setValue(V value);                      //設置原本的value值並返回該值

    boolean equals(Object o);

    int hashCode();
}

boolean equals(Object o);

int hashCode();

}

 

Map與Set相似度極高,將Map中的key和value分離開來看。key組是使用set集合方法來存儲的。不僅如此,在子類的實現方面,兩者也有很多的相似,所以你也會發現兩者子類的命名很相像。

常見的繼承Map接口的實用類

  • HashMap 
    HashMap是線程不安全的實現,且HashMap中可以使用null作為key或者value。
  • LinkedHashMap 
    LinkedHashMap使用一個雙向鏈表來維護key-value對的次序,其也是一個有序的Map集合,順序與key-value對的插入順序保持一致。
  • TreeMap 
    TreeMap是一個紅黑樹的結構,每個key-value作為紅黑樹的一個節點。TreeMap也會對key進行排序,也分為自然排序和定制排序兩種。
  • EnumMap 
    EnumMap是一個與枚舉類一起使用的Map實現。
  • HashTable 
    HashTable是一個比較古老的Map實現類,它是一個線程安全的Map實現,且不允許使用null作為key和value。由於該類是比較久遠的類,其性能較低,所以現在用的也比較少。 
    HashTable判斷value相等的標准是:value與另外一個對象通過equals()方法返回true即可。

實用類對比

  一般的應用場景,使用HashMap已經夠用了。它非常適合於快速查詢。但是如果程序需要一個排序的Map集合,可以考慮使用TreeMap。

操作集合的工具類:Collections

  Java提供了一個操作Set、List和Map等集合的工具類:Collections,該類提供了大量的方法對集合元素進行排序、查詢和修改等操作,還提供了將集合對象設置為不可變、對集合對象實現同步控制。

    • 排序:reverse()(反轉集合元素順序)、shuffle()(隨機排列)、sort()、swap()等方法。
    • 查找和替換:binarySearch(list,obj)(二分查找指定List集合元素obj的索引)、max()、min()、fill()、frequency()(返回指定集合元素的出現次數)、replaceAll()等方法。
    • 同步控制:Collections提供了多個synchronizedXxx()方法,該方法可以將指定的集合包裝成線程同步的集合,進而解決了多線程並發訪問集合時的線程安全問題。
    • 設置不可變集合:Collections提供三個方法來返回一個不可變的集合:emptyXxx()(返回一個空的、不可變的集合對象)、singletonXxx()、unmodifiableXxx()方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM