集合分為單例集合與雙列集合
雙列集合的5種遍歷方式
import java.util.*;
public class day0 {
public static void main(String[] args) {
HashMap sm =new HashMap();
sm.put("abc","zhoguo");
sm.put("123","meiguo");
sm.put("555","yingguo");
//1.通過key獲取
? ? ? ? Set set = sm.keySet();
//自動(dòng)迭代? item:迭代變量
? ? ? ? for (String item : set) {
System.out.println(item+"\t"+sm.get(item));
}
//2.通過value獲取
? ? ? ? Collection values = sm.values();
for (String value : values) {
System.out.println(value);
}
//3.key與value同時(shí)獲取
? ? ? ? Set> entrySet = sm.entrySet();
for (Map.Entry entry : entrySet) {
System.out.println(entry.getKey()+"\t"+entry.getValue());
}
//倆種while
? ? ? ? Iterator iterator = sm.keySet().iterator();
while (iterator.hasNext()){
String key = iterator.next();
System.out.println(key+"\t"+sm.get(key));
}
Iterator> iterator1 = sm.entrySet().iterator();
while (iterator1.hasNext()){
Map.Entry entry = iterator1.next();
System.out.println(entry.getKey()+"\t"+entry.getValue());
}
}
}
java的集合框架中找爱,Collection接口是所有集合的根,然后擴(kuò)展成三大類集合:
List:也就是有序集合落包,提供了方便的訪問意敛,插入艘蹋,刪除等操作
Set:set是不允許出現(xiàn)重復(fù)元素的
Queue/Deque:除了集合的基本功能外,還支持類似先入先出,或者后入先出等特定行為纤房。通常是并發(fā)編程場合却嗡,再并發(fā)包中放著
單列集合自動(dòng)擴(kuò)容
所有語言中底層都是通過數(shù)組相互拷貝實(shí)現(xiàn)的
Vector:擴(kuò)張成原來的2倍
ArrayList:擴(kuò)容成原來的1.5倍
在實(shí)例化List的時(shí)候舶沛,jdk1.8中,默認(rèn)的容量是0窗价,在1.7與1.6中默認(rèn)的是10如庭,當(dāng)通過add方法填入第一個(gè)元素時(shí),元素為10
迭代器
迭代器是Iterator接口,有三個(gè)核心方法坪它,維護(hù)指針可以向下移動(dòng)next()骤竹,移動(dòng)到指定位置后,取出當(dāng)前位置的元素(next)往毡,以及重置指針操作remove
為什么數(shù)組和集合可以使用for循環(huán)進(jìn)行迭代遍歷蒙揣?
所有的數(shù)組和集合都實(shí)現(xiàn)了Iterable接口,該接口中只有一個(gè)方法开瞭,iterator方法懒震,返回值類型是Iterable類型,在iterable中有三個(gè)方法嗤详,hasNest个扰,next,和remove葱色,最主要的是hasNext和next递宅,在底層幫我們?nèi)ゾS護(hù)可以被迭代數(shù)組或集合的迭代
Map集合底層的數(shù)據(jù)結(jié)構(gòu)
List單列結(jié)構(gòu):底層是數(shù)組實(shí)現(xiàn)的
set和map底層是通過數(shù)組和鏈表實(shí)現(xiàn)的
hashset是以hashmap為基礎(chǔ)實(shí)現(xiàn)的
hashset保證元素的位于性,底層是通過hashCodde和equals結(jié)合實(shí)現(xiàn)的苍狰,在對比的過程中办龄,先對比hashcode是否相同,然后對吧equals淋昭。
倆個(gè)對象是同一對象土榴,hashcode一定相同,如果倆個(gè)對象hashcode值相同响牛,不一定是同一個(gè)對象
hashmap底層是哈希列表玷禽,哈希列表中的哈希值
hashMap底層數(shù)據(jù)結(jié)構(gòu)
HasgMap是基于哈希表的Map接口的非同步實(shí)現(xiàn),此實(shí)現(xiàn)提供1所有可選的映射操作呀打,并允許使用null值與null鍵矢赁,此類不保證映射的順序,特別是它不保證該順序永久不變
HashMap的數(shù)據(jù)結(jié)構(gòu)實(shí)際上是一個(gè)鏈表散列的數(shù)據(jù)結(jié)構(gòu)贬丛,即數(shù)組和鏈表的結(jié)合體
HashMap基于Hash算法實(shí)現(xiàn)的撩银,我們通過put存儲,get鍵賴獲取豺憔,當(dāng)傳入key時(shí)额获,HashMap會(huì)根據(jù)key的hashCode()計(jì)算出hash值,根據(jù)hash值將value保存在bucket里恭应,當(dāng)計(jì)算出的hash值相同時(shí)抄邀,我們稱為hash沖突,HashMap的做法時(shí)用鏈表和紅黑樹存儲相同hash值得value昼榛。當(dāng)hash沖突得個(gè)數(shù)比較少時(shí)境肾,使用連表否則使用紅黑樹
線程安全得集合,HashTable,但HashTable訪問速度慢奥喻,底層用得Synchronized關(guān)鍵字偶宫。HashTable雖然線程安全,但他有性能問題有一個(gè)更好得集合环鲤,就是juc包下得ConcurrentHashMap得類型
ConcurrentHashMap與HashMap等得區(qū)別
1.HashMap:
HashMap底層是數(shù)組+鏈表實(shí)現(xiàn)得纯趋,是線程不安全得,在多線程環(huán)境下冷离,使用Hashmap進(jìn)行put操作會(huì)引起死循環(huán)吵冒,導(dǎo)致cpu接近百分之百,所以在并發(fā)情況下不能使用HashMap
2.HashTable:
HashTable和hashMap得實(shí)現(xiàn)原理幾乎一樣酒朵,差別無非是HashTable不運(yùn)行鍵和值為空桦锄,而hashmap允許扎附,hashtable是線程安全得蔫耽,但hashtable線程安全得策略實(shí)現(xiàn)代價(jià)太大,簡單粗暴留夜,get/put所有相關(guān)操作都上鎖匙铡,多線程訪問時(shí),只要有一個(gè)線程訪問碍粥,其他線程就只能阻塞
3.ConcurrentHashMap:
主要就是為了應(yīng)對hashmap在并發(fā)環(huán)境下不安全而誕生得鳖眼,ConcurrentHashMap得設(shè)計(jì)與實(shí)現(xiàn)非常好,大量得利用了volatlle嚼摩,final钦讳,CAS等lock-free技術(shù)來減少鎖帶來得影響
1.簡述集合體系?
集合分為單列集合和雙列集合枕面。
單列集合的頂層是Collection接口愿卒,包括List和Set集合。
List集合的特點(diǎn)是元素可重復(fù)潮秘,有序琼开,有索引,能夠有角標(biāo)操作集合枕荞,有特有的迭代方式ListIterator柜候。包括ArrayList、LinkedList和Vector躏精。
ArrayList集合底層采用的是數(shù)組數(shù)據(jù)結(jié)構(gòu)渣刷,查詢速度比較快,因?yàn)閿?shù)組有索引矗烛,在內(nèi)存中分配的空間是連續(xù)的飞主,但是增刪比較慢。線程不同步,效率高碌识。初始容量為10碾篡。?
LinkedList集合的底層采用的是鏈表數(shù)據(jù)結(jié)構(gòu),增刪速度比較快筏餐,查詢速度比較慢开泽。線程不同步。
Vector底層數(shù)據(jù)結(jié)構(gòu)也是數(shù)組數(shù)據(jù)結(jié)構(gòu)魁瞪,但是線程同步穆律,效率低,特有取出元素的方式是枚舉导俘。因?yàn)樾实吐驮牛鸩奖籄rrayList替代。
Set集合的特點(diǎn)元素是無序的(存入和取出的順序不一致)旅薄,元素不可以重復(fù)辅髓。包括HashSet和TreeSet。
HashSet的底層數(shù)據(jù)結(jié)構(gòu)是哈希表少梁,線程不同步洛口,效率高。保證元素的唯一性額有的依據(jù)是元素的hashCode和equals方法凯沪。如果hashCode不同第焰,不調(diào)用equals方法。如果hashCode相同妨马,才會(huì)調(diào)用equals方法判斷元素是否相同挺举。?
TreeSet的底層數(shù)據(jù)結(jié)構(gòu)是二叉樹,線程不同步烘跺,效率高湘纵。能夠給元素進(jìn)行排序。保證元素唯一性的依據(jù)是compareTo和return0液荸。排序的兩種方式:第一種元素自身實(shí)現(xiàn)Comparable接口瞻佛,重寫compareTo()方法。這種排序方式叫元素的自然排序娇钱,也叫默認(rèn)排序伤柄。第二種是當(dāng)元素自身不具備比較性或者具備的比較性不是所需要的,這時(shí)就讓集合自身具備比較性文搂,當(dāng)集合初始化時(shí)就有了比較性适刀。定義一個(gè)比較器實(shí)現(xiàn)Comparator接口,重寫compare方法煤蹭,定義集合的時(shí)候?qū)⒈容^器作為參數(shù)傳遞給TreeSet的構(gòu)造函數(shù)笔喉,這樣集合就具有了比較性取视。
Map是雙列集合的頂層接口,該集合存儲的是鍵值對常挚,一對一對的往里存作谭,而且要保證鍵的唯一性。包括Hashtable奄毡、HashMap折欠、TreeMap。
Hashtable的底層數(shù)據(jù)結(jié)構(gòu)是哈希表吼过,不可以存儲null鍵和null值锐秦,線程同步,效率低盗忱。JDK1.0.
HashMap的底層數(shù)據(jù)結(jié)構(gòu)是哈希表酱床,可以存儲null鍵和null值,線程不同步趟佃,將Hashtable替代扇谣,JDK1.2效率高。保證鍵的唯一性的依據(jù)是hashCode和equals方法揖闸。
TreeMap的底層數(shù)據(jù)結(jié)構(gòu)是二叉樹揍堕,線程不安全料身,能夠給集合中的鍵排序汤纸。
2.什么時(shí)候使用什么集合?
(1)首先要看是單列還是雙列芹血,是單列的話就用Collection贮泞,雙列就用Map。
(2)要是單列的話看元素是不是要求重復(fù)幔烛,元素重復(fù)的話使用List啃擦,看查詢多還是增刪多,查詢多的話用ArrayList饿悬,增刪多的話用LinkedList令蛉,不確定的話用ArrayList。不重復(fù)的話使用Set狡恬,看是否要求排序珠叔,排序的話用TreeSet,不需要排序用HashSet弟劲。不確定的話用HashSet祷安。
(3)要是雙列的話,看是否要求排序兔乞,要求排序用TreeMap汇鞭,不要求排序用HashMap凉唐,不確定的話用HashMap。
3.Collection(單列)和(Map)雙列的區(qū)別霍骄?
Collection是單列集合台囱,Map是雙列集合。
Map的鍵是唯一的读整,Collection體系中的Set集合中的元素是唯一的玄坦。
Map集合的數(shù)據(jù)結(jié)構(gòu)針對鍵有效,Collection的底層數(shù)據(jù)結(jié)構(gòu)針對元素有效绘沉。
4.遍歷集合的方式有哪些煎楣?
遍歷List集合的方式有普通for、增強(qiáng)for车伞、迭代器Iterator择懂、列表迭代器ListIterator。
遍歷Set集合的方式有增強(qiáng)for另玖、迭代器Iterator困曙。
遍歷map集合的方式有keySet(),entrySet()谦去。然后通過增強(qiáng)for慷丽、迭代器Iterator遍歷。
5.用迭代器和增強(qiáng)for遍歷集合鳄哭,能否用集合的方法操作集合要糊?
不能,會(huì)出現(xiàn)并發(fā)修改異常妆丘,ConcurrentModificationException锄俄。并發(fā)修改異常就是在用普通迭代器的時(shí)候用集合的方法增加、刪除元素勺拣∧淘可以用列表迭代器。