更新時(shí)間:2019-08-23 14:21:40 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽2833次
List和Set的區(qū)別
List,Set都是繼承自Collection接口List特點(diǎn):元素有放入順序,元素可重復(fù),Set特點(diǎn):元素?zé)o放入順序,元素不可重復(fù),重復(fù)元素會(huì)覆蓋掉,(元素雖然無(wú)放入順序,但是元素在set中的位置是有該元素的HashCode決定的,其位置其實(shí)是固定的,加入Set的Object必須定義equals()方法,另外list支持for循環(huán),也就是通過(guò)下標(biāo)來(lái)遍歷,也可以用迭代器,但是set只能用迭代,因?yàn)樗麩o(wú)序,無(wú)法用下標(biāo)來(lái)取得想要的值。)Set和List對(duì)比Set:檢索元素效率低下,刪除和插入效率高,插入和刪除不會(huì)引起元素位置改變。
List:和數(shù)組類(lèi)似,List可以動(dòng)態(tài)增長(zhǎng),查找元素效率高,插入刪除元素效率低,因?yàn)闀?huì)引起其他元素位置改變
HashSet是如何保證不重復(fù)的
向HashSet中add()元素時(shí),判斷元素是否存在的依據(jù),不僅要比較hash值,同時(shí)還要結(jié)合equles方法比較。
HashSet中的add()方法會(huì)使用HashMap的add()方法。以下是HashSet部分源碼:
HashMap是線(xiàn)程安全的嗎,為什么不是線(xiàn)程安全的(最好畫(huà)圖說(shuō)明多線(xiàn)程環(huán)境下不安全)?
不是線(xiàn)程安全的;如果有兩個(gè)線(xiàn)程A和B,都進(jìn)行插入數(shù)據(jù),剛好這兩條不同的數(shù)據(jù)經(jīng)過(guò)哈希計(jì)算后得到的哈希碼是一樣的,且該位置還沒(méi)有其他的數(shù)據(jù)。所以這兩個(gè)線(xiàn)程都會(huì)進(jìn)入我在上面標(biāo)記為1的代碼中。假設(shè)一種情況,線(xiàn)程A通過(guò)if判斷,該位置沒(méi)有哈希沖突,進(jìn)入了if語(yǔ)句,還沒(méi)有進(jìn)行數(shù)據(jù)插入,這時(shí)候CPU就把資源讓給了線(xiàn)程B,線(xiàn)程A停在了if語(yǔ)句里面,線(xiàn)程B判斷該位置沒(méi)有哈希沖突(線(xiàn)程A的數(shù)據(jù)還沒(méi)插入),也進(jìn)入了if語(yǔ)句,線(xiàn)程B執(zhí)行完后,輪到線(xiàn)程A執(zhí)行,現(xiàn)在線(xiàn)程A直接在該位置插入而不用再判斷。這時(shí)候,你會(huì)發(fā)現(xiàn)線(xiàn)程A把線(xiàn)程B插入的數(shù)據(jù)給覆蓋了。發(fā)生了線(xiàn)程不安全情況。本來(lái)在HashMap中,發(fā)生哈希沖突是可以用鏈表法或者紅黑樹(shù)來(lái)解決的,但是在多線(xiàn)程中,可能就直接給覆蓋了。
上面所說(shuō)的是一個(gè)圖來(lái)解釋可能更加直觀。如下面所示,兩個(gè)線(xiàn)程在同一個(gè)位置添加數(shù)據(jù),后面添加的數(shù)據(jù)就覆蓋住了前面添加的。
如果上述插入是插入到鏈表上,如兩個(gè)線(xiàn)程都在遍歷到最后一個(gè)節(jié)點(diǎn),都要在最后添加一個(gè)數(shù)據(jù),那么后面添加數(shù)劇的線(xiàn)程就會(huì)把前面添加的數(shù)據(jù)給覆蓋住。
則在擴(kuò)容的時(shí)候也可能會(huì)導(dǎo)致數(shù)據(jù)不一致,因?yàn)閿U(kuò)容是從一個(gè)數(shù)組拷貝到另外一個(gè)數(shù)組。
HashMap的擴(kuò)容過(guò)程
當(dāng)向容器添加元素的時(shí)候,會(huì)判斷當(dāng)前容器的元素個(gè)數(shù),如果大于等于閾值(知道這個(gè)閾字怎么念嗎?不念fa值,念yu值四聲)---即當(dāng)前數(shù)組的長(zhǎng)度乘以加載因子的值的時(shí)候,就要自動(dòng)擴(kuò)容啦。
擴(kuò)容(resize)就是重新計(jì)算容量,向HashMap對(duì)象里不停的添加元素,而HashMap對(duì)象內(nèi)部的數(shù)組無(wú)法裝載更多的元素時(shí),對(duì)象就需要擴(kuò)大數(shù)組的長(zhǎng)度,以便能裝入更多的元素。當(dāng)然Java里的數(shù)組是無(wú)法自動(dòng)擴(kuò)容的,方法是使用一個(gè)新的數(shù)組代替已有的容量小的數(shù)組,就像我們用一個(gè)小桶裝水,如果想裝更多的水,就得換大水桶。
如果cap是2的n次方,則容量為cap,否則為大于cap的第一個(gè)2的n次方的數(shù)。
Java反射機(jī)制
Java反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類(lèi),都能夠獲得這個(gè)類(lèi)的所有屬性和方法,對(duì)于任意一個(gè)對(duì)象都能夠調(diào)用它的任意一個(gè)屬性和方法。這種在運(yùn)行時(shí)動(dòng)態(tài)的獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱(chēng)為Java的反射機(jī)制。
Class類(lèi)與java.lang.reflect類(lèi)庫(kù)一起對(duì)反射的概念進(jìn)行了支持,該類(lèi)庫(kù)包含了Field,Method,Constructor類(lèi)(每個(gè)類(lèi)都實(shí)現(xiàn)了Member接口)。這些類(lèi)型的對(duì)象時(shí)由JVM在運(yùn)行時(shí)創(chuàng)建的,用以表示未知類(lèi)里對(duì)應(yīng)的成員。
這樣你就可以使用Constructor創(chuàng)建新的對(duì)象,用get()和set()方法讀取和修改與Field對(duì)象關(guān)聯(lián)的字段,用invoke()方法調(diào)用與Method對(duì)象關(guān)聯(lián)的方法。另外,還可以調(diào)用getFields()getMethods()和getConstructors()等很便利的方法,以返回表示字段,方法,以及構(gòu)造器的對(duì)象的數(shù)組。這樣匿名對(duì)象的信息就能在運(yùn)行時(shí)被完全確定下來(lái),而在編譯時(shí)不需要知道任何事情。
運(yùn)行結(jié)果:無(wú)參構(gòu)造器Run………..有參構(gòu)造器Run………..Apple
異常分類(lèi)以及處理機(jī)制
Java標(biāo)準(zhǔn)庫(kù)內(nèi)建了一些通用的異常,這些類(lèi)以Throwable為頂層父類(lèi)。
Throwable又派生出Error類(lèi)和Exception類(lèi)。
錯(cuò)誤:Error類(lèi)以及他的子類(lèi)的實(shí)例,代表了JVM本身的錯(cuò)誤。錯(cuò)誤不能被程序員通過(guò)代碼處理,Error很少出現(xiàn)。
因此,程序員應(yīng)該關(guān)注Exception為父類(lèi)的分支下的各種異常類(lèi)。
異常:Exception以及他的子類(lèi),代表程序運(yùn)行時(shí)發(fā)送的各種不期望發(fā)生的事件。可以被Java異常處理機(jī)制使用,是異常處理的核心。
總體上我們根據(jù)Javac對(duì)異常的處理要求,將異常類(lèi)分為二類(lèi)。
非檢查異常(unckeckedexception):Error和RuntimeException以及他們的子類(lèi)。javac在編譯時(shí),不會(huì)提示和發(fā)現(xiàn)這樣的異常,不要求在程序處理這些異常。所以如果愿意,我們可以編寫(xiě)代碼處理(使用try…catch…finally)這樣的異常,也可以不處理。對(duì)于這些異常,我們應(yīng)該修正代碼,而不是去通過(guò)異常處理器處理。這樣的異常發(fā)生的原因多半是代碼寫(xiě)的有問(wèn)題。如除0錯(cuò)誤ArithmeticException,錯(cuò)誤的強(qiáng)制類(lèi)型轉(zhuǎn)換錯(cuò)誤ClassCastException,數(shù)組索引越界ArrayIndexOutOfBoundsException,使用了空對(duì)象NullPointerException等等。
檢查異常(checkedexception):除了Error和RuntimeException的其它異常。javac強(qiáng)制要求程序員為這樣的異常做預(yù)備處理工作(使用try…catch…finally或者throws)。在方法中要么用try-catch語(yǔ)句捕獲它并處理,要么用throws子句聲明拋出它,否則編譯不會(huì)通過(guò)。這樣的異常一般是由程序的運(yùn)行環(huán)境導(dǎo)致的。因?yàn)槌绦蚩赡鼙贿\(yùn)行在各種未知的環(huán)境下,而程序員無(wú)法干預(yù)用戶(hù)如何使用他編寫(xiě)的程序,于是程序員就應(yīng)該為這樣的異常時(shí)刻準(zhǔn)備著。如SQLException,IOException,ClassNotFoundException等。
需要明確的是:檢查和非檢查是對(duì)于javac來(lái)說(shuō)的,這樣就很好理解和區(qū)分了。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話(huà)與您溝通安排學(xué)習(xí)
初級(jí) 202925
初級(jí) 203221
初級(jí) 202629
初級(jí) 203743