Java——集合
前言
????????相信做開發(fā)的老鐵們铁追,不管你是做Java姻成、Android、還是其他的語言昙楚,我相信很多都遇到過集合這個名詞近速,而且我相信很多的老鐵在進行大公司面試的時候,一定不可避免的會被問到關(guān)于集合這個問題堪旧,本人以前對這些基礎(chǔ)的東西理解的非常淺削葱,但隨著這幾年的開發(fā)發(fā)現(xiàn)集合對于項目開發(fā)是非常重要的。如果能合理的運用集合的幾個實現(xiàn)類淳梦,那么事情可能達到事半功倍的效果析砸,所以本人也做一些筆記鞏固一下知識。
正文
首先集合的分類:Collection and Map爆袍。但是從源碼的角度去看首繁,發(fā)現(xiàn)這兩個其實本不是java類作郭,而是Java接口,個人覺得這就是Java現(xiàn)在面向接口編程的最忠實的寫照.
Collection:
????????首先我們的知道Collection并不是我們想象中的衍生出它的實現(xiàn)類弦疮,而是實現(xiàn)了另外的兩個接口夹攒,List and Set?衍生出的這兩個接口是互補的。
首先我們必須知道為什么會衍生出兩個接口(兩個接口的不同之處)
Set:
????????是無序并且是不可重復(fù)胁塞,集合中的對象不按特定的方式排序咏尝,只是簡單地把對象加入集合中
List:
????????有序并且是可重復(fù)的,里面存儲的對象是有序的,而且List提供了幾個關(guān)于索引的方法啸罢。查詢速度快编检。因為往list集合里插入或刪除數(shù)據(jù)時,會伴隨著后面數(shù)據(jù)的移動扰才,所有插入刪除數(shù)據(jù)速度慢蒙谓。
兩個接口的不同點說完了,我們來了解一下在集合中不得不提到的一個重要的環(huán)節(jié)
循環(huán)--------------------->平時可能大家說的遍歷训桶。
????????在我們這兩大集合接口中不可獲取的肯定是去遍歷這個集合暖眼,常用List的老鐵們可能在平時的List的使用方法中用到的都是比較傳統(tǒng)方式就是
for(int i = 0;i < list.size();i++){
//處理的邏輯代碼
}
或者是高級for循環(huán)
for(Ob ob:obs){-------------------->這里的ob是我對對象的簡稱,希望大家能夠理解
//處理的邏輯代碼
}
????????以上的這種循環(huán)的處理方式位岔。但是這種方式只能適用于List這個接口實現(xiàn)遍歷的方式校赤,那么我們的Set接口如何來實現(xiàn)遍歷呢。創(chuàng)造集合的大神早已想到了這一點午绳。所以在集合中就衍生了另外一個遍歷集合的另外一個方式
Iterator------>中文名稱叫迭代器置侍。
????????它是專門負責集合的遍歷的一個接口。在它的基礎(chǔ)之上拦焚,也衍生了一個ListIterator這個專門為List專用的迭代器蜡坊。使用的方法也很簡單。首先我們必須獲取到當前List或者是Set整個集合對象的迭代器赎败,然后對整個迭代器進行遍歷秕衙。示例代碼如下:
Iterator iterator = arr.iterator();
while(iterator .hasNext()){
? ? Ob ob = ?iterator.next();
}
就是這么簡單容易。
下面我再來介紹一下List的結(jié)合相關(guān)的子類:ArrayList和LinkedList
????????ArrayList和LinkedList在用法上的區(qū)別:了解這些僵刮,能讓你在日常的開發(fā)中合理的運用相關(guān)的實現(xiàn)類据忘,來提高程序的效率。這也是你做一些大數(shù)據(jù)處理的時候提高程序效率的一個重要的點搞糕。
1勇吊、LinkedList經(jīng)常用在增刪操作較多而查詢操作很少的情況下,ArrayList則相反窍仰。
2汉规、ArrayList是實現(xiàn)了基于動態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)驹吮。
3针史、對于隨機訪問get和set膏燕,ArrayList絕對優(yōu)于LinkedList,因為LinkedList要移動指針悟民。
4坝辫、對于新增和刪除操作add和remove,LinkedList比較占優(yōu)勢射亏,因為ArrayList要移動數(shù)據(jù)近忙。?這一點要看實際情況的。若只對單條數(shù)據(jù)插入或刪除智润,ArrayList的速度反而優(yōu)于LinkedList及舍。但若是批量隨機的插入刪除數(shù)據(jù),LinkedList的速度大大優(yōu)于ArrayList. 因為ArrayList每插入一條數(shù)據(jù)窟绷,要移動插入點及之后的所有數(shù)據(jù)锯玛。
在我復(fù)習集合的資料整理的過程中,另外還有一個集合那就是------------------>Vector
首先我們通過源碼知道兼蜈,Vector是矢量隊列攘残,它繼承了AbstractList,實現(xiàn)了List为狸、 RandomAccess, Cloneable, java.io.Serializable接口歼郭。
Vector繼承了AbstractList,實現(xiàn)了List辐棒,它是一個隊列病曾,因此實現(xiàn)了相應(yīng)的添加、刪除漾根、修改泰涂、遍歷等功能。
Vector實現(xiàn)了RandomAccess接口辐怕,因此可以隨機訪問逼蒙。
Vector實現(xiàn)了Cloneable,重載了clone()方法秘蛇,因此可以進行克隆其做。
Vector實現(xiàn)了Serializable接口,因此可以進行序列化赁还。
Vector的操作是線程安全的。
所以這就是Vector具備的一些相關(guān)屬性驹沿。
Vector的數(shù)據(jù)結(jié)構(gòu)和ArrayList差不多艘策,包含了3個成員變量:elementData,elementCount渊季,capacityIncrement朋蔫。
(1)elementData是Object[]的數(shù)組罚渐,初始大小為10,會不斷的增長驯妄。
(2)elementCount是元素的個數(shù)荷并。
(3)capacityIncrement是動態(tài)數(shù)組增長的系數(shù)。
Vector有四種遍歷方式:
(1)第一種通過迭代器遍歷青扔,即通過Iterator去遍歷? ? ? ? ? ?? ? ?
Integer value=null;
Iterator iter=vector.iterator();
while(iter.hasNext())
{
value=(Interger)iter.next();
}
(2)第二種隨機訪問源织,通過索引進行遍歷
Integer value=null;
int size=vector.size();
for(int i=0;i
{
value=vector.get(i);
}
(3)第三種通過for循環(huán)的方式
Integer value=null;
for( Integer inte: vector)
{
value=inte;
}
(4)第四種,Enumeration遍歷??
Integer value=null;
Enumeration enu=vector.elements();
while(enu.hasMoreElements())
{
value=(Integer)enu.nextElement();
}
從上面的寫法我們能夠得些什么呢微猖?
1谈息、首先他是一個實實在在Java class;
2、如果使用Vector凛剥,它又有了自己專屬的迭代器Enumeration侠仇。
關(guān)于List相關(guān)的集合類我們就介紹在這里,下面我們來介紹一下集合中第二個很重要的重要的接口---->
Map
????????map相信很多人都知道并且用過犁珠,map存儲數(shù)據(jù)的方式是通過鍵值對的方式進行存儲(key-value)逻炊。所以呢,因為它是鍵值對的方式犁享,那么就必須要保證它的鍵(key)是唯一的嗅骄,通過key去檢索到value(值),值可以不是唯一,這是它的一大特性饼疙。接下來說一下map集合實現(xiàn)類溺森,然后呢通過實現(xiàn)類來總結(jié)一下map的遍歷方式
map的實現(xiàn)類:HashMap、Hashtable窑眯、LinkedHashMap和TreeMap屏积,這幾個是常用的實現(xiàn)類。
HashMap?
????????HashMap是最常用的Map磅甩,它根據(jù)鍵的HashCode值存儲數(shù)據(jù)炊林,根據(jù)鍵可以直接獲取它的值,具有很快的訪問速度卷要,遍歷時渣聚,取得數(shù)據(jù)的順序是完全隨機的。因為鍵對象不可以重復(fù)僧叉,所以HashMap最多只允許一條記錄的鍵為Null奕枝,允許多條記錄的值為Null,是非同步的
Hashtable
????????Hashtable與HashMap類似瓶堕,是HashMap的線程安全版隘道,它支持線程的同步,即任一時刻只有一個線程能寫HashTable,因此也導(dǎo)致了HashTable在寫入時會比較慢谭梗,它繼承自Dictionary類忘晤,不同的是它不允許記錄的鍵或者值為null,同時效率較低激捏。所以當需要實現(xiàn)線程同步设塔,而數(shù)據(jù)量比較小時,還是可以使用HashTable的
ConcurrentHashMap
????????線程安全远舅,并且鎖分離闰蛔。ConcurrentHashMap內(nèi)部使用段(Segment)來表示這些不同的部分,每個段其實就是一個小的hash?table表谊,它們有自己的鎖钞护。只要多個修改操作發(fā)生在不同的段上,它們就可以并發(fā)進行爆办。
LinkedHashMap
????????LinkedHashMap保存了記錄的插入順序难咕,在用Iteraor遍歷LinkedHashMap時,先得到的記錄肯定是先插入的距辆,在遍歷的時候會比HashMap慢余佃,有HashMap的全部特性。
TreeMap
????????TreeMap實現(xiàn)SortMap接口跨算,能夠把它保存的記錄根據(jù)鍵排序爆土,默認是按鍵值的升序排序(自然順序),也可以指定排序的比較器诸蚕,當用Iterator遍歷TreeMap時步势,得到的記錄是排過序的。不允許key值為空背犯,非同步的坏瘩;
接下來我們講一下map的遍歷,兩種方式 :keySet() ? and ?entrySet()
第一種:KeySet()
將Map中所有的鍵存入到set集合中漠魏。因為set具備迭代器倔矾。所有可以迭代方式取出所有的鍵,再根據(jù)get方法柱锹。獲取每一個鍵對應(yīng)的值哪自。 keySet():迭代后只能通過get()取key?。
取到的結(jié)果會亂序禁熏,是因為取得數(shù)據(jù)行主鍵的時候壤巷,使用了HashMap.keySet()方法,而這個方法返回的Set結(jié)果匹层,里面的數(shù)據(jù)是亂序排放的隙笆。
典型用法如下:
Map map = new HashMap();
map.put("key1","data1");
map.put("key2","data12");
map.put("key3","data123");
map.put("key4","data1234");
//首先獲取到map集合中所有鍵的set集合锌蓄,keyset()升筏,方法如下
Iterator it = map.keySet().iterator();
//獲取到迭代器然后通過遍歷得到key,然后通過get(key)的方法得到Object
while(it.hasNext()){
Object key = it.next();
System.out.println(map.get(key));
}
第二種:entrySet()
Set> entrySet() //返回此映射中包含的映射關(guān)系的 Set 視圖撑柔。(一個關(guān)系就是一個鍵-值 ?對),就是把(key-value)作為一個整體一對一對地存放在Set集合當中您访。Map.Entry表示映射關(guān)系铅忿。entrySet():迭代后可以e.getKey(),e.getValue()兩種方法來取key和value灵汪。返回的是Entry接口檀训。
典型用法如下:
Map map = new HashMap();
map.put("key1","data1");
map.put("key2","data12");
map.put("key3","data123");
map.put("key4","data1234");
//將map集合中的映射關(guān)系取出,存入到set集合
Iterator it = map.entrySet().iterator();
while(it.hasNext()){
Entry e =(Entry) it.next();
System.out.println("鍵"+e.getKey () + "的值為" + e.getValue());
}
推薦使用第二種方式享言,即entrySet()方法峻凫,效率較高。
對于keySet其實是遍歷了2次览露,一次是轉(zhuǎn)為iterator荧琼,一次就是從HashMap中取出key所對應(yīng)的value。而entryset只是遍歷了第一次差牛,它把key和value都放到了entry中命锄,所以快了。兩種遍歷的遍歷時間相差比較明顯偏化。
總結(jié)
? ? ? ? 集合是我們在開發(fā)中不可或缺的一個關(guān)鍵而且比較重要的環(huán)節(jié)脐恩,我在復(fù)習的過程中也明白了許多自己以前還是有很多不知道的地方,比如在前段時間可以在開發(fā)中對于map集合的遍歷都不是很懂侦讨,只是會寫驶冒,現(xiàn)在由于空閑時間比較多,仔細的研究了一下韵卤,還是有一種豁然開朗的趕腳骗污。所以希望這些東西能夠給老鐵們有所幫助。最后希望所有的程序員老鐵都能寫出高質(zhì)量的代碼怜俐,升職加薪身堡。。拍鲤。贴谎。走上人生巔峰。