集合中的線程初體驗

java零基礎入門-高級特性篇(四)? HashSet 和 Collections

本章繼續(xù)講集合如失,先來看看Set集合绊诲。Set集合的特點,1:無序褪贵,2:無重復掂之。上一章講了HashMap抗俄,最后提到HashSet的底層實現(xiàn)其實就是HashMap。那么為什么用HashMap就可以實現(xiàn)無序和不重復世舰,下面看看具體如何使用HashMap實現(xiàn)HashSet动雹。

hashset和hashmap的區(qū)別

hashset底層用hashmap實現(xiàn),那為什么不直接用hashmap就完了跟压,非要整個hashset出來胰蝠?

集合

如果有這個問題,可以回頭看看前面講的集合框架的設計裆馒。設計hashset是用來保存那種不需要使用下標操作元素姊氓,并且不能重復的集合。set集合的元素和List集合的元素一樣喷好,都是一個對象翔横。而hashmap的元素是key-value鍵值對,因為數(shù)據(jù)存儲類型不同梗搅,所以需要將set和map區(qū)分開來禾唁。看一下圖无切,幫助回憶一下荡短。

hashmap如何實現(xiàn)hashset

Set集合最重要的一個方法就是add(E e),如何往一個Set集合添加元素哆键,了解了添加元素的原理掘托,查找元素理解起來就簡單許多。hashset的add方法籍嘹,用的就是是hashmap的put方法闪盔。下面是源代碼:

map.put(e,PRESENT) == null

這里需要重點理解的是,一個對象如何存入一個key-value辱士。從上面這句代碼中泪掀,可以發(fā)現(xiàn),在往set集合添加元素的時候颂碘,這個元素被用來當做map的key异赫,而value是一個常量。

為什么直接將對象作為key呢头岔?因為hashmap使用哈希算法對key進行計算塔拳,計算后的結果就是底層數(shù)組的位置,所以當使用hashset的時候峡竣,需要對放進set的對象進行哈希計算蝙斜,至于value,hashset不關心澎胡。

hashmap的key的特性就是不會重復孕荠,后添加相同的數(shù)據(jù)會將前一個數(shù)據(jù)覆蓋掉娩鹉。正好滿足了set集合不重復的特性,所以直接用hashmap即可以滿足hashset集合的要求稚伍。


關系

其實這里容易繞暈的是幾個底層實現(xiàn)的結構弯予,這里用一個圖來說明一下。HashSet利用HashMap的Key的特性來實現(xiàn)个曙,而HashMap是利用數(shù)組和鏈表的特性來實現(xiàn)锈嫩,這樣應該明白這幾個結構之間的關系了吧。

這次hashset真的講完了垦搬。

Collections工具

使用集合存放數(shù)據(jù)的時候呼寸,會有很多情況要對集合進行操作。特別是List集合猴贰,因為List集合的有序性对雪,會需要按照特定的順序操作集合,而java也專門提供了Collections工具來對集合進行操作米绕。下面來看看幾個例子

List list = new ArrayList();

list.add("one");//此處省略 瑟捣,一共添加五個元素one,two栅干,three迈套,fore,five

Collections方法

Collection.reverse(list);//反轉集合元素的順序

Collection.shuffle(list);//隨機順序碱鳞,多次隨機結果可能不一樣

Collection.sort(list);//升序排序桑李,先數(shù)字后字母,數(shù)字0-9窿给,字母A-Z a-z的順序贵白,逐位比較

Collection.swap(list,0填大,3);//交換第一個和第四個元素位置

看一個swap的源碼實現(xiàn)

Object tmp = arr[i];

arr[i] = arr[j];

arr[j] = temp;

嗯,完了俏橘,是不是有一種這玩意我都會寫允华,干嘛要用這個的感覺?其實確實可以自己寫寥掐,但是一般提供工具給別人用靴寂,肯定要提供全套,再就是合理的使用工具會減少不必要的代碼召耘,提升代碼的可讀性百炬。

Collection 和 Collections

這兩個長得很像,但是作用差別很大污它,初學者切勿將兩者概念混淆剖踊。Collection是集合體系中的上層接口庶弃,而Collections是操作集合的工具。何謂工具德澈?還記不記得我們講的靜態(tài)方法歇攻?不記得的快去復習類和對象的文章。

Collections作為一個工具類梆造,里面提供的方法都是靜態(tài)方法缴守,所以在上面的例子中,都是直接使用類Collections來調(diào)用方法镇辉,Collections提供了大量的靜態(tài)方法來操作集合屡穗,有沒有加深對靜態(tài)成員這個概念的理解?

用Collections工具類創(chuàng)建線程安全的集合

上次講vector的時候忽肛,說了他是線程安全的集合村砂,而List是線程不安全的。但是可以通過一些方法讓List變成線程安全的麻裁,所以vector目前已經(jīng)沒有使用的必要了箍镜。那么如何讓List變成線程安全的集合呢?答案就是使用Collections工具可以將List變?yōu)榫€程安全煎源。

Collections有一系列的synchronized方法來使集合變?yōu)榫€程安全的色迂,一系列是指不僅僅可以將List變?yōu)榫€程安全的,Set手销,Map也有方法變成線程安全的歇僧。

List list = Collections.synchronizedList(new ArrayList());

Set set = Collections.synchronizedSet(new HashSet());

Map map = Collections.synchronizedMap(new HashMap());

使用以上三個工具方法就可以將普通集合變?yōu)榫€程安全的集合。這些方法有什么魔法么锋拖,為什么外面包一層就線程安全了诈悍?下面來簡單介紹一下多線程以及使用多線程會遇到的問題。

多線程是什么兽埃?

多線程就是并行處理問題侥钳。比如去銀行取錢,如果只有一個取款機隊伍就會排很長柄错,但是如果有多個取款機同時辦理業(yè)務舷夺,速度就會快很多。這就是多線程的思路售貌,多個線程(取款機)處理一個問題(取錢)给猾。

多個ATM

為什么多線程有安全問題?

假設現(xiàn)在有2個人要取款颂跨,如果2個人同時操作一個取款機會發(fā)生什么敢伸?第一個人密碼輸了3位數(shù),第二個人跑來按3位數(shù)恒削,第一個人刪了準備重新輸池颈,又被第二個人按了3下尾序,這樣下去兩個人都別想取錢。多個線程搶同一個資源就會產(chǎn)生線程安全問題饶辙,實際開發(fā)中遇到的線程安全問題會比這種情況還要復雜蹲诀。

怎么解決?

帶鎖的ATM

新款取款機弃揽,帶門帶鎖的脯爪!一旦一個人進去了,先鎖門矿微,然后就可以放心大膽的取錢了痕慢,這時候沒有人會來跟你搶著取錢了。代碼里面也是可以上鎖的涌矢,所以線程安全的集合都是帶有鎖機制的掖举。

高效并發(fā)容器

這里是補充知識,了解即可娜庇。其實上面的這幾個方法確實可以將普通集合轉為線程安全的集合塔次,但是實現(xiàn)很粗糙,導致效率不是很高名秀。所以就有了專門為并發(fā)情況設計的更加高效的并發(fā)容器励负,比如CopyOnWriteArrayList,CopyOnWriteArraySet匕得,ConcurrentHashMap继榆。

上鎖也是有很多種上鎖的方法,繼續(xù)取錢的例子汁掠。

最極端粗暴的上鎖方式就是略吨,銀行每次只準進一個人,這樣絕對不會有任何問題考阱,絕對安全翠忠,銀行所有保安都盯著你,你還能玩出花來乞榨?但是這樣做效率極端底下秽之。比如老版本的vector和hashtable就是用類似這種粗暴的方法來上鎖。

再來看稍微先進點的上鎖方式姜凄。就是銀行可以進很多人政溃,但是辦理不同業(yè)務的分開來趾访,取錢的一個隊态秧,存錢的一個隊,辦理財換密碼再來一個隊扼鞋,每個隊同時只能一個人辦申鱼,辦的人進小房間愤诱,上鎖。這種上鎖的粒度比上面那種要小捐友,效率要快很多淫半。

最后就是最先進的鎖了。也就是類似并發(fā)容器這種匣砖,升級版的取款機不僅可以取錢還可以存錢科吭,還能辦其他業(yè)務~也就是說不管辦什么業(yè)務,找個人最少的隊排著就行了猴鲫,所有機器可以同時辦相同或者不同的業(yè)務对人。這種鎖的粒度最小,只對操作對象的數(shù)據(jù)進行上鎖拂共,效率最高牺弄。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市宜狐,隨后出現(xiàn)的幾起案子势告,更是在濱河造成了極大的恐慌,老刑警劉巖抚恒,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咱台,死亡現(xiàn)場離奇詭異,居然都是意外死亡柑爸,警方通過查閱死者的電腦和手機吵护,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來表鳍,“玉大人馅而,你說我怎么就攤上這事∑┦ィ” “怎么了瓮恭?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長厘熟。 經(jīng)常有香客問我屯蹦,道長,這世上最難降的妖魔是什么绳姨? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任登澜,我火速辦了婚禮,結果婚禮上飘庄,老公的妹妹穿的比我還像新娘脑蠕。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布谴仙。 她就那樣靜靜地躺著迂求,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晃跺。 梳的紋絲不亂的頭發(fā)上揩局,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音掀虎,去河邊找鬼凌盯。 笑死,一個胖子當著我的面吹牛烹玉,可吹牛的內(nèi)容都是我干的十气。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼春霍,長吁一口氣:“原來是場噩夢啊……” “哼砸西!你這毒婦竟也來了?” 一聲冷哼從身側響起址儒,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤芹枷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后莲趣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸳慈,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年喧伞,在試婚紗的時候發(fā)現(xiàn)自己被綠了走芋。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡潘鲫,死狀恐怖翁逞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情溉仑,我是刑警寧澤挖函,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站浊竟,受9級特大地震影響怨喘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜振定,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一必怜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧后频,春花似錦梳庆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至残揉,卻和暖如春胧后,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抱环。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工壳快, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人镇草。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓眶痰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親梯啤。 傳聞我的和親對象是個殘疾皇子竖伯,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Java集合類可用于存儲數(shù)量不等的對象,并可以實現(xiàn)常用的數(shù)據(jù)結構如棧,隊列等,Java集合還可以用于保存具有映射關...
    小徐andorid閱讀 1,942評論 0 13
  • 原文地址 Java集合 Java集合框架:是一種工具類,就像是一個容器可以存儲任意數(shù)量的具有共同屬性的對象因宇。 Ja...
    gyl_coder閱讀 978評論 0 8
  • Collection ├List │├LinkedList │├ArrayList │└Vector │└Stac...
    AndyZX閱讀 877評論 0 1
  • 在一個方法內(nèi)部定義的變量都存儲在棧中七婴,當這個函數(shù)運行結束后,其對應的棧就會被回收察滑,此時打厘,在其方法體中定義的變量將不...
    Y了個J閱讀 4,418評論 1 14
  • 周末陪娃上課外班的時候户盯,談談媽一邊曬兒子的繪畫作品,一邊吐槽對學校教育的不滿: 你們不知道饲化,現(xiàn)在私立小學一年級就開...
    職場二寶媽頻道閱讀 480評論 0 0