5比搭、類加載器
程序在啟動的時候,并不會一次性加載程序所要用的所有class文件,而是根據(jù)程序的需要,通過Java的類加載機制(ClassLoader)來動態(tài)加載某個class文件到內(nèi)存當(dāng)中的槐脏,從而只有class文件被載入到了內(nèi)存之后,才能被其它class所引用撇寞。所以ClassLoader就是用來動態(tài)加載class文件到內(nèi)存當(dāng)中用的顿天。
5.1堂氯、雙親委派原理
每個ClassLoader實例都有一個父類加載器的引用(不是繼承關(guān)系,是一個包含的關(guān)系)牌废,虛擬機內(nèi)置的類加載器(Bootstrap ClassLoader)本身沒有父類加載器祖灰,但是可以用做其他ClassLoader實例的父類加載器。
當(dāng)一個ClassLoader 實例需要加載某個類時畔规,它會試圖在親自搜索這個類之前先把這個任務(wù)委托給它的父類加載器,這個過程是由上而下依次檢查的恨统,首先由頂層的類加載器Bootstrap CLassLoader進行加載叁扫,如果沒有加載到,則把任務(wù)轉(zhuǎn)交給Extension CLassLoader視圖加載畜埋,如果也沒有找到莫绣,則轉(zhuǎn)交給AppCLassLoader進行加載,還是沒有的話悠鞍,則交給委托的發(fā)起者对室,由它到指定的文件系統(tǒng)或者網(wǎng)絡(luò)等URL中進行加載類。還沒有找到的話咖祭,則會拋出CLassNotFoundException異常掩宜。否則將這個類生成一個類的定義,并將它加載到內(nèi)存中么翰,最后返回這個類在內(nèi)存中的Class實例對象牺汤。
5.2、 為什么使用雙親委托模型
JVM在判斷兩個class是否相同時浩嫌,不僅要判斷兩個類名是否相同檐迟,還要判斷是否是同一個類加載器加載的。
避免重復(fù)加載码耐,父類已經(jīng)加載了追迟,則子CLassLoader沒有必要再次加載。
考慮安全因素骚腥,假設(shè)自定義一個String類敦间,除非改變JDK中CLassLoader的搜索類的默認(rèn)算法,否則用戶自定義的CLassLoader如法加載一個自己寫的String類束铭,因為String類在啟動時就被引導(dǎo)類加載器Bootstrap CLassLoader加載了每瞒。
6、集合
Java集合類主要由兩個接口派生出:Collection和Map纯露,這兩個接口是Java集合的根接口剿骨。
Collection接口是集合類的根接口,Java中沒有提供這個接口的直接的實現(xiàn)類埠褪。但是卻讓其被繼承產(chǎn)生了兩個接口浓利,就是 Set和List挤庇。Set中不能包含重復(fù)的元素。List是一個有序的集合贷掖,可以包含重復(fù)的元素嫡秕,提供了按索引訪問的方式。
Map是Java.util包中的另一個接口苹威,它和Collection接口沒有關(guān)系昆咽,是相互獨立的,但是都屬于集合類的一部分牙甫。Map包含了key-value對掷酗。Map不能包含重復(fù)的key,但是可以包含相同的value窟哺。
6.1泻轰、區(qū)別
List,Set都是繼承自Collection接口,Map則不是;
List特點:元素有放入順序且轨,元素可重復(fù); Set特點:元素?zé)o放入順序浮声,元素不可重復(fù),重復(fù)元素會覆蓋掉旋奢,(注意:元素雖然無放入順序泳挥,但是元素在set中的位置是有該元素的HashCode決定的,其位置其實是固定的至朗,加入Set 的Object必須定義equals()方法;
LinkedList羡洁、ArrayList、HashSet是非線程安全的爽丹,Vector是線程安全的;
HashMap是非線程安全的筑煮,HashTable是線程安全的;
6.2、List和Vector比較
Vector是多線程安全的粤蝎,線程安全就是說多線程訪問同一代碼真仲,不會產(chǎn)生不確定的結(jié)果。而ArrayList不是初澎,這個可以從源碼中看出秸应,Vector類中的方法很多有synchronized進行修飾,這樣就導(dǎo)致了Vector在效率上無法與ArrayList相比碑宴;
兩個都是采用的線性連續(xù)空間存儲元素软啼,但是當(dāng)空間不足的時候,兩個類的增加方式是不同延柠。
Vector可以設(shè)置增長因子祸挪,而ArrayList不可以。
Vector是一種老的動態(tài)數(shù)組贞间,是線程同步的贿条,效率很低雹仿,一般不贊成使用。
6.3整以、HashSet如何保證不重復(fù)
HashSet底層通過HashMap來實現(xiàn)的胧辽,在往HashSet中添加元素是
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
在HashMap中進行查找是否存在這個key,value始終是一樣的公黑,主要有以下幾種情況:
如果hash碼值不相同邑商,說明是一個新元素,存凡蚜;
如果hash碼值相同人断,且equles判斷相等,說明元素已經(jīng)存在番刊,不存;
如果hash碼值相同影锈,且equles判斷不相等芹务,說明元素不存在,存鸭廷;
如果有元素和傳入對象的hash值相等枣抱,那么,繼續(xù)進行equles()判斷辆床,如果仍然相等佳晶,那么就認(rèn)為傳入元素已經(jīng)存在,不再添加讼载,結(jié)束轿秧,否則仍然添加;
6.4咨堤、HashSet與Treeset的適用場景
HashSet是基于Hash算法實現(xiàn)的菇篡,其性能通常都優(yōu)于TreeSet。為快速查找而設(shè)計的Set一喘,我們通常都應(yīng)該使用HashSet驱还,在我們需要排序的功能時,我們才使用TreeSet凸克。
TreeSet 是二叉樹(紅黑樹的樹據(jù)結(jié)構(gòu))實現(xiàn)的,Treeset中的數(shù)據(jù)是自動排好序的议蟆,不允許放入null值
HashSet是哈希表實現(xiàn)的,HashSet中的數(shù)據(jù)是無序的,可以放入null萎战,但只能放入一個null咐容,兩者中的值都不能重復(fù),就如數(shù)據(jù)庫中唯一約束蚂维。
HashSet是基于Hash算法實現(xiàn)的疟丙,其性能通常都優(yōu)于TreeSet颖侄。為快速查找而設(shè)計的Set,我們通常都應(yīng)該使用HashSet享郊,在我們需要排序的功能時览祖,我們才使用TreeSet。
6.5炊琉、HashMap與TreeMap展蒂、HashTable的區(qū)別及適用場景
HashMap 非線程安全,基于哈希表(散列表)實現(xiàn)苔咪。使用HashMap要求添加的鍵類明確定義了hashCode()和equals()[可以重寫hashCode()和equals()]锰悼,為了優(yōu)化HashMap空間的使用,您可以調(diào)優(yōu)初始容量和負(fù)載因子团赏。其中散列表的沖突處理主要分兩種箕般,一種是開放定址法,另一種是鏈表法舔清。HashMap的實現(xiàn)中采用的是鏈表法丝里。
TreeMap:非線程安全基于紅黑樹實現(xiàn),TreeMap沒有調(diào)優(yōu)選項体谒,因為該樹總處于平衡狀態(tài)
原文鏈接:https://blog.csdn.net/xiangzhihong8/java/article/details/96280254
點擊下方鏈接免費獲取Android進階資料: