小編給大家分享一下Java中集合是什么,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),黃山區(qū)企業(yè)網(wǎng)站建設(shè),黃山區(qū)品牌網(wǎng)站建設(shè),網(wǎng)站定制,黃山區(qū)網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷(xiāo),網(wǎng)絡(luò)優(yōu)化,黃山區(qū)網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專(zhuān)業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。Java Collection API提供了一些列的類(lèi)和接口來(lái)幫助我們存儲(chǔ)和管理對(duì)象集合。其實(shí)Java中的集合工作起來(lái)像是一個(gè)數(shù)組,不過(guò)集合的大小是可以動(dòng)態(tài)改變的,而且集合也提供了更多高級(jí)功能。有了JavaCollectionAPI,我們就不需要自己編寫(xiě)集合類(lèi)了,大部分Java集合類(lèi)都位于java.util
包里面,還有一些和并發(fā)相關(guān)的集合類(lèi)位于java.util.concurrent
包中。
一、Java 集合概覽
Java中的集合有兩大類(lèi),分別是:
1. Collection
2. Map
Collection類(lèi)的集合可以理解為主要存放的是單個(gè)對(duì)象,而Map類(lèi)的集合主要存儲(chǔ)的是key-value類(lèi)型的對(duì)象。這兩大類(lèi)即可理所當(dāng)然的對(duì)應(yīng)著兩個(gè)接口,分別是Collection接口
和Map接口
,下面這幅圖列出了這兩個(gè)接口的繼承樹(shù):
從上面這幅圖可以看到,Collection接口又衍生了出三個(gè)分支,分別是:
1. List
2. Set
3. Queue
而Map則相對(duì)簡(jiǎn)單,只有一個(gè)分支。下面我們就詳細(xì)介紹Java Collection的每一個(gè)實(shí)現(xiàn)類(lèi)。
注意:要把Collection、Collections區(qū)分開(kāi),Collection是集合的一個(gè)接口,而Collections是一個(gè)工具類(lèi),它提供了一些靜態(tài)方法來(lái)方便我們操作集合的實(shí)例,這兩個(gè)都位于java.util
包中。
二、先從Collection接口介紹
下圖是Collection接口的源碼截圖,從接口中的抽象方法我們可以看出,它定義了一個(gè)通用集合常用的方法:
- 增加刪除一個(gè)元素
- 判斷元素是否存在
- 獲得集合的大小
- 迭代一個(gè)集合
2.1 Collection的List接口
List接口繼承自Collection接口,它的特點(diǎn)是其中的對(duì)象是有序的,并且每個(gè)對(duì)象都有一個(gè)唯一的index,我們可以通過(guò)這個(gè)index來(lái)搜索某個(gè)元素,并且List中的對(duì)象允許重復(fù),這類(lèi)似于一個(gè)數(shù)組。對(duì)于List接口,Java API提供了如下實(shí)現(xiàn):
- java.util.ArrayList
- java.util.LinkedList
- java.util.Vector
- java.util.Stack
當(dāng)然,在 java.util.concurrent
包中也有一些實(shí)現(xiàn),這些內(nèi)容會(huì)在另一篇文章中詳細(xì)介紹。
ArrayList是最常用的集合,其內(nèi)部實(shí)現(xiàn)是一個(gè)數(shù)組,ArrayList的大小是可以動(dòng)態(tài)擴(kuò)充的。對(duì)于元素的隨機(jī)訪問(wèn)效率高,其訪問(wèn)的時(shí)間復(fù)雜度為O(1)
,對(duì)于數(shù)據(jù)的插入與刪除,從尾部操作效率高,時(shí)間復(fù)雜度和隨機(jī)訪問(wèn)一樣是O(1)
,若是從頭部操作則效率會(huì)比較低,因?yàn)閺念^部插入或刪除時(shí)需要移動(dòng)后面所有元素,其時(shí)間復(fù)雜度為O(n-i)
(n表示元素個(gè)數(shù),i表示元素位置)。
LinkList:從上圖可以看出,不但繼承了List
接口,還繼承了Deque
接口(后面會(huì)介紹)。LinkList是一個(gè)基于鏈表的數(shù)據(jù)結(jié)構(gòu),每個(gè)節(jié)點(diǎn)都保存了上一個(gè)和下一個(gè)節(jié)點(diǎn)的指針。LinkList對(duì)于隨機(jī)訪問(wèn)效率是比較低的,因?yàn)樗枰獜念^開(kāi)始索引,所以其時(shí)間復(fù)雜度為O(i)
。但是對(duì)于元素的增刪,LinkList效率高,因?yàn)橹恍枰薷那昂笾羔樇纯?,其時(shí)間復(fù)雜度為O(1)
。
Vector:從Vector和ArrayList源碼截圖可以看出,它們繼承的接口完全一致。所以,Vector可以看做是一個(gè)線程安全的ArrayList,它內(nèi)部也是基于數(shù)組實(shí)現(xiàn)的,不過(guò)幾乎所有的集合操作都加了synchronized
關(guān)鍵字。
Stack:上面是Stack類(lèi)源碼截圖,我們看到Stack類(lèi)其實(shí)繼承自Vector,Stack只是在Vector的基礎(chǔ)上添加了幾個(gè)方法以提供棧(Last In First Out LIFO)的特性。Stack的特點(diǎn)是添加時(shí)新元素會(huì)被添加到頂部,移除時(shí)頂部的元素最先被移除。這種數(shù)據(jù)結(jié)構(gòu)主要用作一些特殊數(shù)據(jù)加工流程,如語(yǔ)言編譯、XML解析等。
2.2 Collection的Set接口
Set和List接口一樣也是繼承自Collection
接口,同樣是對(duì)集合的一種實(shí)現(xiàn),它們之間大的區(qū)別是Set中的對(duì)象不允許重復(fù)。對(duì)于Set
接口,Java API提供了如下實(shí)現(xiàn):
- java.util.EnumSet
- java.util.HashSet
- java.util.LinkedHashSet
- java.util.TreeSet
這些類(lèi)的功能稍有不同,區(qū)別主要體現(xiàn)在對(duì)象的迭代的順序及插入、查找的效率上。
HashSet的實(shí)現(xiàn)很簡(jiǎn)單,其內(nèi)部就是一個(gè)HashMap
,不過(guò)它對(duì)元素的順序沒(méi)有保證。
LinkedHashSet的實(shí)現(xiàn)也很簡(jiǎn)單,其內(nèi)部用的是一個(gè)LinkedHashMap
。因?yàn)?code>LinkedHashMap內(nèi)部維護(hù)了一個(gè)雙向鏈表以保持順序,所以LinkedHashSet
的特點(diǎn)是它當(dāng)中的元素是有序的,元素迭代的順序就是其插入的順序,元素的再次插入不會(huì)影響原有元素的順序。
TreeSet:從上圖的繼承關(guān)系可以看出,想要了解TreeSet
就要先了解NavigableSet
和SortedSet
接口。
SortedSet接口
public interface SortedSetextends Set { Comparator super E> comparator(); SortedSet subSet(E fromElement, E toElement); SortedSet headSet(E toElement); SortedSet tailSet(E fromElement); E first(); }
從上面接口定義看,SortedSet接口是Set的一個(gè)子接口,它除了有一般Set的特性之外它元素在內(nèi)部是有序的。它內(nèi)部元素的順序取決于元素的排序規(guī)則,即元素順序取決于元素對(duì)comparable
接口的實(shí)現(xiàn)或者一個(gè)comparator
比較器,關(guān)于comparable和comparator的區(qū)別,可以參考:https://www.jb51.net/article/93973.htm
NavigableSet接口
public interface NavigableSetextends SortedSet { NavigableSet descendingSet(); Iterator descendingIterator(); SortedSet headSet(E toElement); SortedSet tailSet(E fromElement); SortedSet subSet(E fromElement, E toElement); ceiling(), floor(), higher(), and lower() ... }
從NavigableSet接口定義可以看到,它是SortedSet的一個(gè)子接口,并且提供了一些導(dǎo)航方法,至于這些導(dǎo)航方法的含義大家可以查看Java Doc。
所以,TreeSet的特點(diǎn)就是內(nèi)部元素有序,并且有很多導(dǎo)航方法的實(shí)現(xiàn)。從第一部分Java集合類(lèi)概覽中我們知道,Set有一個(gè)子接口SortedSet
,而SortedSet又有一個(gè)子接口NavigableSet
接口,Java API對(duì)SortedSet、NavigableSet接口的實(shí)現(xiàn)只有一個(gè),就是TreeSet
。
2.3 Collection的Queue接口
Queue接口繼承自Collection
接口,它也代表了一個(gè)有序的隊(duì)列,不過(guò)這個(gè)隊(duì)列大的特點(diǎn)就是新插入的元素位于隊(duì)列的尾部,移除的對(duì)象位于隊(duì)列的頭部,這類(lèi)似于超市中結(jié)賬的隊(duì)列。
我們通過(guò)第一節(jié)的Java集合概覽已經(jīng)知道,Queue接口還有一個(gè)子接口Deque,下面我們分別看一下JavaAPI對(duì)這兩個(gè)接口的定義:
Queue接口:
public interface Queueextends Collection { boolean add(E e); boolean offer(E e); E remove(); E poll(); E peek(); }
Deque接口:
public interface Dequeextends Queue { void addFirst(E e); void addLast(E e); E removeFirst(); E removeFirst(); }
從這兩個(gè)接口的定義我想大家已經(jīng)看出些端倪,Queue接口定義了一般隊(duì)列的操作方式,而Deque則是一個(gè)雙端隊(duì)列。
對(duì)于Queue
接口,Java API提供了兩個(gè)實(shí)現(xiàn):
- java.util.LinkedList(也實(shí)現(xiàn)了Deque接口)
- java.util.PriorityQueue
LinkedList:前面的List章節(jié)已經(jīng)提到,它是一個(gè)標(biāo)準(zhǔn)隊(duì)列。
PriorityQueue:隊(duì)列中的順序類(lèi)似于TreeSet,取決于元素的排序規(guī)則,即元素對(duì)comparable接口的實(shí)現(xiàn)或者一個(gè)comparator比較器。
對(duì)于Deque接口,出了LinkList類(lèi)之外還有一個(gè)實(shí)現(xiàn):
- java.util.ArrayDeque
ArrayDeque:從名稱可以看出,其內(nèi)部實(shí)現(xiàn)是一個(gè)數(shù)組。
三、Java 集合之 Map
從第一部分Java集合類(lèi)概覽中我們知道,Map不是繼承自Collection接口,而是和Collection接口出于并列的位置。所以,Map的行為和上面介紹的Collection的行為由很大不同。Map的主要特點(diǎn)是它存放的元素為key-value
對(duì),我們看一下Map接口的定義:
public interface Map{ V put(K key, V value); boolean containsKey(Object key); Set > entrySet(); int hashCode(); V get(Object key); Set keySet(); ... ... }
對(duì)于Map接口,Java API提供了如下實(shí)現(xiàn):
- java.util.HashMap
- java.util.Hashtable
- java.util.EnumMap
- java.util.IdentityHashMap
- java.util.LinkedHashMap
- java.util.Properties
- java.util.TreeMap
- java.util.WeakHashMap
其中,我們最常用到的是HashMap和TreeMap。
HashMap中的key、value都是無(wú)序的。HashMap的內(nèi)部實(shí)現(xiàn)非常值得研究,具體請(qǐng)參考HashMap內(nèi)部實(shí)現(xiàn)
HashTable可以看做是HashMap的重量級(jí)實(shí)現(xiàn),其中的大部分方法都加了synchronized關(guān)鍵字,是線程安全的。HashTable
與HashMap的另一個(gè)區(qū)別是HashMap的key-value
都允許為null,而HashTable不
可以。
LinkedHashMap也是一個(gè)HashMap,只是內(nèi)部維護(hù)了一個(gè)雙向鏈表以保持順序,LinkedHashSet
內(nèi)部實(shí)現(xiàn)就是用的LinkedHashMap。
TreeMap中的key、value不但可以保持順序,類(lèi)似于TreeSet
和PriorityQueue
,TreeMap中key、value的迭代順序取決于它們各自的排序規(guī)則。
以上是“Java中集合是什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!