這本書很早以前就開始看了,但一直也沒完整的看完,這個週末終於把剩餘的內容都補上了。抓緊把讀書筆記一齊整理下。java
前面十幾章的內容其實在開發過程當中都已經理解得比較到位了,但關於容器部分特別是容器的深刻使用相關內容仍是掌握不夠,因此先整理容器:算法
- LinkedHashSet按照元素插入的順序保存元素,而TreeSet按照排序順序維護元素
- SortedSet:Comparator comparator()返回當前set使用的Comparator,或者返回null,表示天然方式排序;Object first()返回容器總的第一個元素;Object last()返回容器中的最末一個元素;SortedSet subSet(fromElement, toElement)生成此Set的本身,範圍從fromElement(包含)到toElement(不包含);SortedSet headSet(toElement)生成此Set的子集,由小於toElement的元素組成;SortedSet tailSet(fromElement)生成此Set的子集,由大於或等於fromElement的元素組成
- SortedSet的意思是「按對象的比較函數對元素排序」,而不是指「元素插入的次序」。插入順序能夠用LinkedHashSet來保存
- Queue在java se5中只有兩個實現,LinkedList和PriorityQueue,他們的差別在排序行爲
- 雙向隊列:就像是一個隊列,可是能夠在任何一端添加或移除元素,在LinkedList中包含支持雙向隊列的方法,可是在java標準類庫中沒有任何顯式地用於雙向隊列的接口。所以可使用組合來建立一個Deque類,並直接從LinkedList中暴露
- 映射表(也稱爲關聯數組)的基本思想是它維護的是鍵值(對)關聯,所以你可使用鍵來查找值。標準的java類庫中包含了Map的幾種基本實現,包括
- HashMap:使用了hashCode()來進行散列,hashCode爲java的Object根類的方法,插入和查詢「鍵值對」的開銷是固定的,能夠經過構造器設置容量和負載因子以調整容器的性能:默認的Object.equals()比較的是對象的地址,HashMap使用equals()判斷當前鍵是否與表中存在的鍵相同,正確的equals應知足如下5個條件
- 對任何不是null的x,x.equals(null)必定返回false
- 一致性:對於任意x和y,若是對象中用於等價比較的信息沒有改變,那麼不管調用x.equals(y)多少次,返回結果老是一致地
- 傳遞性:對任意x,y,z若x.equals(y)=true,且y.equals(z)=true,則x.equals(z)=true
- 對稱性:若x.equals(y)= true,則y.equals(x)=true
- 自反性:x.equals(x) = true
- 若是要使用本身的類做爲HashMap的鍵,必須同時重載hashCode()和equals()方法
- TreeMap:基於紅黑樹的實現,查看「鍵」或「鍵值對」時,他們會被排序(次序由Comparable或Comparator)決定。TreeMap的特色在於,所獲得的結果是通過排序的。TreeMap是惟一帶有subMap()方法的Map,能夠返回一個子樹。
- LinkedHashMap:相似於HahsMap,可是迭代遍歷它取得「鍵值對」的順序是其插入次序,或者是LRU次序,只比HashMap慢一點,而在迭代訪問時反而更快,由於它使用鏈表維護內部次序。
- WeakHashMap:弱鍵(weak key)映射,容許釋放映射所指向的對象;這是爲解決某類特殊問題而設計的。若是映射以外沒有引用指向「某個鍵」,則此「鍵」將被GC回收。
- ConcurrentHashMap:一種線程安全的Map,他不涉及同步加鎖
- IdentityHashMap:使用==代替equals()對「鍵」進行比較的散列映射,專門爲解決特殊問題而設計的
- 若是不覆蓋hashCode()和equals()將沒法使用散列的數據結構有:HashSet、HashMap、LinkedHashSet、LinkedHashMap
- 設計hashCode()時最重要的因素就是:不管什麼時候,對同一個對象,調用hashCode()都應該生成一樣的值
- Set可被實現爲:
- TreeSet:HashSet最經常使用,查詢速度最快。它惟一緣由是它能夠維持元素的排序狀態。TreeSet迭代一般比用HashSet要快
- HashSet:基於TreeMap。生成一個老是處於排序狀態的Set。性能基本上老是比TreeSet好,特別是在添加和查詢元素時,而這兩個操做也是最重要的操做。
- LinkedHashSet:保持元素插入的次序。對於插入操做LinkedHashSet比HashSet的代價還高,這是由維護鏈表所帶來額外開銷形成的
- Map可被實現爲:
- IdentityHashMap:全部的Map實現的插入操做都會隨着Map尺寸的變大而明顯變慢。查找的代價一般比插入要小得多
- HashTable的性能大致上與HashMap至關,HashMap是用來替代HashTable的
- TreeMap:一般比HashMap慢,與TreeSet同樣,TreeMap是一種建立有序隊列的方式
- LinkedHashMap:在插入時比HashMap慢一點,由於它維護散列數據結構的同時還要維護鏈表,正是因爲這個列表,使得其迭代速度更快
- HashMap的性能因子:
- 容量:表中的桶位數
- 初始容量:表在建立時所擁有的桶位數。HashMap和HashSet都具備容許你指定初始容量的構造器
- 尺寸:表中當前存儲的項數
- 負載因子:尺寸/容量。默認負載因子0.75,這個因子在時間和空間代價之間達到了平衡,更高的負載因子能夠下降表所需的空間,可是會增長查找代價
- SoftReference、WeakReference和PhantomReference由強到弱排列,對應不一樣級別的「可得到性」
- SoftReference:用以實現內存敏感的高速緩存
- WeakReference:爲實現「規範映射」而設計的,它不妨礙垃圾回收器回收映射的「鍵」(或「值」)。規範映射中對象的實例能夠在程序的多處被同時使用,以節省存儲空間
- PhantomReference:用一調度會收錢的清理工做,它比Java終止機制更靈活
其他內容整理:設計模式
訪問控制權限:1.Java訪問權限修飾詞:public、protected、包訪問權限(默認訪問權限)和private。數組
2.包訪問權限:當前包中的全部其餘類對那個成員具備訪問權限,但對於這個包以外的全部類,這個成員倒是private。緩存
3.protected:繼承訪問權限。有時基類的建立者會但願有某個特定成員,把對它的訪問權限賦予派生類而不是全部類。這就須要protected來完成這一工做。protected也提供包訪問權限,也就是說,相同包內的其餘類均可以訪問protected元素。protected指明「就類用戶而言,這是private的,但對於任何繼承於此類的導出類或其餘任何位於同一個包內的類來講,它倒是能夠訪問的」。好比:
基類:安全
package access.test ;
public class Test {
public Test () {
System.out.println("Test Constructor");
}
void func1() { // 包訪問權限,其它包即便是子類也不能訪問它
System.out.println("func1");
}
}
子類:數據結構
import access.test.Test ;
public class Chip extends Test {
public Chip() {
System.out.println("Chip constructor");
}
public void func2() {
func1(); // error, the method func1() from the type Test is not visible
}
}
能夠發現子類並不能訪問基類的包訪問權限方法。此時能夠將Test 中的func1指定爲public,但這樣作全部的人就都有了訪問權限,爲了只容許子類訪問,能夠將func1指定爲protected便可。函數
組合和繼承之間的選擇:1.組合和繼承都容許在新的類中放置子對象,組合是顯式的這樣作,而繼承則是隱式的作。2.組合技術一般用於想在新類中使用現有類的功能而非它的接口這種情形。即在新類中嵌入某個對象,讓其實現所須要的功能,但新類的用戶看到的只是爲新類所定義的接口,而非所嵌入對象的接口。爲取得此效果,須要在新類中嵌入一個現有類的private對象。但有時,容許類的用戶直接訪問新類中的組合成分是極具意義的,即將成員對象聲明爲public。若是成員對象自身都隱藏了具體實現,那麼這種作法是安全的。當用戶可以瞭解到你正在組裝一組部件時,會使得端口更加易於理解。好比Car對象可由public的Engine對象、Wheel對象、Window對象和Door對象組合。但務必要記得這僅僅是一個特例,通常狀況下應該使域成爲private。3.在繼承的時候,使用某個現有類,並開發一個它的特殊版本。一般,這意味着你在使用一個通用類,併爲了某種特殊須要而將其特殊化。稍微思考一下就會發現,用一個「交通工具」對象來構成一部「車子」是毫無心義的,由於「車子」並不包含「交通工具」,它僅是一種交通工具(is-a關係)。4.「is-a」(是一個)的關係是用繼承來表達的,而「has-a」(有一個)的關係則是用組合來表達。5.究竟是該用組合仍是繼承,一個最清晰的判斷方法就是問一問本身是否須要重新類向基類進行向上轉型,須要的話就用繼承,不須要的話就用組合方式。工具
final關鍵字:性能
1.對final關鍵字的誤解:當final修飾的是基本數據類型時,它指的是數值恆定不變(就是編譯期常量,若是是static final修飾,則強調只有一份),而對對象引用而不是基本類型運用final時,其含義會有一點使人迷惑,由於用於對象引用時,final使引用恆定不變,一旦引用被初始化指向一個對象,就沒法再把它指向另外一個對象。然而,對象其自身倒是能夠被修改的,Java並未提供使任何對象恆定不變的途徑(但能夠本身編寫類以取得使對象恆定不變的效果),這一限制一樣適用數組,它也是對象。
2.使用final方法真的能夠提升程序效率嗎:將一個方法設成final後,編譯器就能夠把對那個方法的全部調用都置入「嵌入」調用裏。只要編譯器發現一個final方法調用,就會(根據它本身的判斷)忽略爲執行方法調用機制而採起的常規代碼插入方法(將自變量壓入堆棧;跳至方法代碼並執行它;跳回來;清除堆棧自變量;最後對返回值進行處理)。相反,它會用方法主體內實際代碼的一個副原本替換方法調用。這樣作可避免方法調用時的系統開銷。固然,若方法體積太大,那麼程序也會變得雍腫,可能受到到不到嵌入代碼所帶來的任何性能提高。由於任何提高都被花在方法內部的時間抵消了。
策略設計模式與適配器模式的區別:
- 策略設計模式
建立一個可以根據所傳遞的參數對象的不一樣而具備不一樣行爲的方法,被稱爲策略設計模式,這類方法包含所要執行的算法中固定不變的部分,而「策略」包含變化的部分。策略就是傳遞進去的參數對象,它包含要執行的代碼。
- 適配器模式 在你沒法修改你想要使用的類時,可使用適配器模式,適配器中的代碼將接受你所擁有的接口,併產生你所須要的接口。