***Collections類
public
static <T> List<T> nCopies(
int n, T o) 用單個對象的引用填充Collection
public
static <T>
void fill (List<?
super T> list, T obj) { 替換已經在list中存在的元素,不能添加新的元素。
***填充容器 所有Collection子類型都有接受另一個Collection對象的構造器,用接受對象中的元素來填充新的容器。
***可選操作 執行各種不同的添加和移除的方法在Collection介面中都是可選操作,這意味著實作類別 並不需要為這些方法提供功能定義。 可選操作聲明調用某些方法將不會執行有意義的行為,反而會拋出異常。 定義可選操作的目的:防治在設計中出現介面爆炸的情況。它使Java容器類庫能達到易學易用的目標。未獲支援的操作是一種特例,可以延時到需要的時候再實現。但為了能使這種方式工作: 1 UnsupportedOperationException必須是一種罕見事件。 2 若一個操作是未獲支援的,那麼在實現介面的時候可能就會導致UnsupportedOperationException,而不是將產品程式交給客戶以後才出現。因為它表示了編程上有錯誤:使用了不正確的介面實現。 最常見的未獲支援的操作,都來源於背後由固定尺寸的資料結構支援的容器。 1 使用Arrays.
asList將數群組轉換為List時
2 Collections.
unmodifiableList (
new ArrayList<String>())建立的不可修改的容器 對於將容器作為參數接受的方法,其文檔應該指定哪些可選方法必須實現。
***List的功能方法 常用:add 添加對象, get一次取出一個元素, iterator擷取用於該序列的iterator
***Set Set介面: 元素唯一,不保證維護元素次序 HashSet:尋找速度快,存入元素必須定義hashCode() TreeSet:保持次序,底層為樹結構。使用它可以從Set中提取有序的序列。元素必須實現Comparable介面 LinkedHashSet:具有HashSet的速度,且內部使用鏈表維護元素的順序(插入的次序),必須定義hashCode() SortedSet:按對象的比較函數對元素排序
***隊列 除並發外,Queue實現包括LinkedList,PriorityQueue.其差異在於排序行為而不是效能。可以將元素從隊列的一段插入,另一端取出。除了優先順序隊列,Queue都為FIFO。 優先順序隊列:可通過儲存實現了Comparable介面的對象,按照compareTo()確定對象的優先順序實現控制元素儲存順序。 雙向隊列:可以在任一段添加移除元素。Java類庫中無用於雙向隊列的介面。但LinkedList包含支援雙向隊列的方法,可使用組合方式利用其來實現Deque<T>類,但不常用。
***Map 映射表(關聯陣列)的基本思想是它維護的是索引值關聯,因此可以用鍵來尋找值。在映射表中執行線性搜尋速度很慢。 HashMap使用了散列碼進行快速查詢,散列碼是每個對象都有的int值(Object類中的hashCode()) 。 Map基於散列表的實現。插入和查詢“索引值對”的開銷是固定的。可以通過構造器設定容量capacity和負載因子load factor,以調整容器的效能。
LinkedHashMap:類似於HashMap,但是迭代遍曆它時,取得“索引值對”的順序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一點。而在迭代訪問時發而更快,因為它使用鏈表維護內部次序。
TreeMap:基於紅/黑樹狀結構資料結構的實現。查看“鍵”或“索引值對”時,它們會被排序(次序由Comparabel或Comparator決定)。TreeMap的特點在於,你得到的結果是經過排序的。TreeMap是唯一的帶有subMap()方法的Map,它可以返回一個子樹。
WeakHashMap : 弱鍵(weak key)Map,Map中使用的對象也被允許釋放:這是為解決特殊問題設計的。如果沒有map之外的引用指向某個“鍵”,則此“鍵”可以被垃圾收集器回收。
IdentifyHashMap : 使用==代替equals()對“鍵”作比較的hash map。專為解決特殊問題而設計。
任何鍵都必須有equals(),如果鍵被用於散列Map,那麼它必須具備恰當的hashCode(),如果鍵被用於TreeMap,那麼它必須實現Comparable。
***散列與散列碼 預設的Object.equals()只是比較對象的地址,預設的hashCode()使用對象的地址計算散列碼,所以一個Groundhog(3)並不等於另一個Groundhog(3)。因此,若想使用自己的類作為HashMap的鍵,必須同時重載hashCode()和equals(). 正確的equals()必須滿足以下條件: 1 自反性。對任意x,x.equals(x)一定返回true 2 對稱性。對任意x,y. 如果x.equals(y)==true,那麼y.equals(x)==true 3 傳遞性。對任意x,y,z.若x.equals(y)==true,y.equals(z)==true那麼x.equals(z)==true 4 一致性。對任意x,y.若對象中用於等價比較的資訊沒有改變,那麼無論調用多少次x.equals(y),結果應該一致。 5 對任何不是null的x,x.equals(null)返回false
使用散列的目的在於:使用一個對象來尋找另一個對象。其關鍵點在於速度,而提高速度必須快速的尋找到鍵。Hashing的目的在於將key存放到一個能快速尋找到的地方。它使用一個array來存放index值(因為array尺寸固定,不能直接存放資料,已不能直接存放hashcode,因此使用固定大小的array存放索引值,hashcode % size = index),每個index值對應一個list,鍵和值被儲存到這個list中。應用時,首先找到index值,然後對對應的list進行線性查詢,這個過程是慢的,但好的雜湊演算法會使值均勻分布在list中。 自訂hashCode(): 重要的原則是不論hashCode()何時被調用,特定對象都會產生特定的hashCode值,否則put()和get()時hashCode不同,則無法找到對象。我們有時不想每個新對象都會產生不同的hashCode(預設是Object產生的),而是想通過對象中的值是否相同來決定是否產生新hashCode,因此需要自訂方法.
***選擇合適的容器 List:預設情況下應選擇ArrayList.當存在大量的插入刪除操作並影響效能時,可考慮使用 LinkedList(實現了雙向鏈表,每個對象都包含List中上一個對象和下一個對象的引用,因此適合在列表中做插入刪除操作)。如果元素個數固定,可以使用Arrays.asList()得到固定大小的List,或者直接使用Array。 Set:預設選擇HashSet,其add()和contains()速度快.當需要排序的set時,才選擇TreeSet(其iterate()速度較快)。LinkedHashSet add()耗時比HashSet多,因為其維持列表與hash容器一致有額外的花費. Map:首選HashMap,因此速度快。當需要頻繁排序時,選擇TreeMap。 除IdentityHashMap外其餘map插入操作會隨map變大而變慢。Hashtable和Hashmap速度相同,因HashMap要替代Hashtable,所以底層實現原理相同。LinkedHashMap插入速度稍慢,因其要保留插入順序,因此其iteration速度快。 HashMap參數: Initial capacity:初始化容量。如果會儲存很多條目,應調大初始化容量,避免頻繁的rehash。 Load factor:到達此閾值後,capacity會加倍,並進行rehash。0.75是比較折中的值。 List的排序和尋找: 對array排序時若使用Comparator,則在尋找時必須使用相同的Comparator進行尋找。 唯讀Collections Map List<String> a = Collections.
unmodifiableList(
new ArrayList<String>(
data ));
unmodifiableCollection
unmodifiableSet
unmodifiableSortedSet
unmodifiableMap
unmodifiableSortedMap
通過這些方法,可以在類內部提供private可寫的容器,而對外提供唯讀容器。 同步的Collections Map,文法同上 Collection<String> c = Collections.
synchronizedCollection(
new ArrayList<String>());
Fail fast: java容器有Fail fast機制,以防止多個地方同時對容器進行操作。如果使用過程中檢測到其他人修改容器,則會拋出異常:ConcurrentModification- Exception. The ConcurrentHashMap, CopyOnWriteArrayList, and CopyOnWriteArraySet use techniques that avoid ConcurrentModificationExceptions
Reference: 在 java.lang.ref庫中,使gc更為靈活。如想保持對一個對象的引用,但又允許其被gc回收,可使用Reference對對象進行引用,包含 SoftReference, WeakReference, and PhantomReference。SoftReference用於記憶體敏感的快取。
SoftReference 的原理是:在保持對對象的引用時保證在 JVM 報告記憶體不足情況之前將清除所有的軟引用。
WeakReference 類的一個典型用途就是正常化映射(canonicalized mapping)。另外,對於那些生存期相對較長而且重新建立的開銷也不高的對象來說,弱引用也比較有用, 不管當前記憶體空間足夠與否,都會回收它的記憶體 。
PhantomReference 類只能用於跟蹤對被引用對象即將進行的收集。 虛引用”顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用並不會決定對象的生命週期。如果一個對象僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被記憶體回收行程回收。