Java集合類

參考:https://www.cnblogs.com/zhouyuqin/p/5168573.html

Java集合總結
  Java集合是每個Java程序員在日常開發(fā)中都會使用到,而且有時候使用得好的話乐设,能事半功倍驹愚。細數Java集合,其實比較常見的就是List裤纹、Set、Map和Queue案狠,在這四者之中服傍,除了Map之外钱雷,其他三個接口都繼承于Collection。
  在這里吹零,首先我們要明確的是罩抗,List、Set灿椅、Map和Queue其實只是以接口的形式存在著的套蒂,所以在日常的程序開發(fā)中,請不要出現說想要直接初始化它們的想法和做法茫蛹,雖然筆者也曾經犯過這樣子的錯誤操刀。

繼承與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類盈包,故其封裝了一個動態(tài)的沸呐、允許再分配的Object[]數組,ArrayList用initialCapacity參數來設置該數組的長度续语,當長度超過預設值后垂谢,ArrayList會動態(tài)增加。
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類撞叽,其也是封裝了一個動態(tài)分配的Object[]數組,也可以使用initialCapacity參數來設置該數組的長度砰识。
Vector是線程安全的能扒,但是也因此Vector的性能很差佣渴。
Stack
  Stack是繼承與Vector的子類辫狼,它主要用來模擬”棧“辛润,因此也具備了peek()膨处、pop()、push()等主要用于棧操作的方法砂竖。
  由于Stack是一個比較古老的Java集合類真椿,它同樣是線程安全的,但也因此暴露出了性能較差的缺點乎澄,如果程序中要使用棧這樣的數據結構的話突硝,可以試一試ArrayDeque,該類也是List的實現類置济,但和LinkedList一樣也繼承了Deque接口解恰。
實用類對比


image.png

使用List集合有以下建議:
1、遍歷集合元素浙于。ArrayList和Vector使用get()方法來獲取遍歷元素护盈,LinkedList應該采用迭代器來遍歷集合元素。
2羞酗、插入和刪除腐宋。當這類操作較多的時候,優(yōu)先考慮使用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可以確保集合元素處于排序狀態(tài)。TreeSet使用紅黑樹來維護集合元素的次序冯丙。如果實現comparator()方法肉瓦,可以實現定制排序遭京。如果采用自然排序,則返回null泞莉。
TreeSet集合的特有方法:first()哪雕、last()、lower(Object e)(返回指定元素之前的元素)鲫趁、higher(Object e)(返回指定元素之后的元素)等等斯嚎。
下面我們說一說TreeSet的定制排序和自然排序:
1、 定制排序
通過Comparator接口的幫助挨厚,實現降序排序堡僻。
2、 自然排序
TreeSet通過CompareTo(Object obj)比較元素之間的大小關系疫剃,將集合元素按升序排列钉疫。實現元素必須實現Comparable元素,而且在比較的時候如果出現不同類型時要轉換類型后比較巢价。
EnumSet
EnumSet是專門為枚舉類設計的集合類牲阁,EnumSet中的所有元素都必須是指定枚舉類型的枚舉值,該枚舉類型在創(chuàng)建EnumSet時顯式或隱式地指定壤躲。
EnumSet在內部以位向量的形式存儲城菊,十分緊湊、高效碉克,因此EnumSet對象占用內存很小凌唬,且運行效率很高。但是該集合元素中不允許加入null元素棉胀。
實用類對比


image.png

繼承與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的實現體制很相像半夷,都會采用了動態(tài)可再分配的數組來存儲集合元素婆廊。但是其在用途上主要是被當作”棧“來使用巫橄。
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集合方法來存儲的王悍。不僅如此破镰,在子類的實現方面,兩者也有很多的相似压储,所以你也會發(fā)現兩者子類的命名很相像鲜漩。

常見的繼承Map接口的實用類
HashMap
HashMap是線程不安全的實現,且HashMap中可以使用null作為key或者value集惋。
LinkedHashMap
LinkedHashMap使用一個雙向鏈表來維護key-value對的次序孕似,其也是一個有序的Map集合,順序與key-value對的插入順序保持一致刮刑。
TreeMap
TreeMap是一個紅黑樹的結構喉祭,每個key-value作為紅黑樹的一個節(jié)點养渴。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()方法轻腺,該方法可以將指定的集合包裝成線程同步的集合,進而解決了多線程并發(fā)訪問集合時的線程安全問題划乖。
設置不可變集合:Collections提供三個方法來返回一個不可變的集合:emptyXxx()(返回一個空的贬养、不可變的集合對象)、singletonXxx()琴庵、unmodifiableXxx()方法误算。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末仰美,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子儿礼,更是在濱河造成了極大的恐慌咖杂,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚊夫,死亡現場離奇詭異诉字,居然都是意外死亡,警方通過查閱死者的電腦和手機知纷,發(fā)現死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門壤圃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人琅轧,你說我怎么就攤上這事伍绳。” “怎么了乍桂?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵冲杀,是天一觀的道長。 經常有香客問我睹酌,道長权谁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任忍疾,我火速辦了婚禮闯传,結果婚禮上,老公的妹妹穿的比我還像新娘卤妒。我一直安慰自己甥绿,他們只是感情好,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布则披。 她就那樣靜靜地躺著共缕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪士复。 梳的紋絲不亂的頭發(fā)上图谷,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機與錄音阱洪,去河邊找鬼便贵。 笑死,一個胖子當著我的面吹牛冗荸,可吹牛的內容都是我干的承璃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蚌本,長吁一口氣:“原來是場噩夢啊……” “哼盔粹!你這毒婦竟也來了隘梨?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤舷嗡,失蹤者是張志新(化名)和其女友劉穎轴猎,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體进萄,經...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡捻脖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了垮斯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片郎仆。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖兜蠕,靈堂內的尸體忽然破棺而出扰肌,到底是詐尸還是另有隱情,我是刑警寧澤熊杨,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布曙旭,位于F島的核電站,受9級特大地震影響晶府,放射性物質發(fā)生泄漏桂躏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一川陆、第九天 我趴在偏房一處隱蔽的房頂上張望剂习。 院中可真熱鬧,春花似錦较沪、人聲如沸鳞绕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽们何。三九已至,卻和暖如春控轿,著一層夾襖步出監(jiān)牢的瞬間冤竹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工茬射, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鹦蠕,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓在抛,卻偏偏與公主長得像片部,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子霜定,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內容