《Java编程思想》学习笔记9——集合容器高级
1.Arrays.asList()方法產生的List是一個固定長度的數組,只支持不改變長度的操作,任何試圖改變其底層數據結構長度的操作(如,增加,刪除等操作)都會拋出UnsupportedOperationException異常。
為了使Arrays.asList()方法產生的List集合長度可變,可以將其作為集合容器的構造方法參數,如:
Set set = new HashSet(Arrays.asList(newint[]{1,23}));
或者將其作為Collections.addAll()方法的參數,如:
Collections.addAll(Arrays.asList(new int[]{1,23}));
2.SortedSet是一個對其元素進行排序了的Set,SortedSet接口有以下方法:
(1).Comparator comparator():
返回此Set中元素進行排序的比較器,如果該方法返回null,則默認使用自然排序。
(2).Object first():
返回Set中第一個(最低)元素。
(3).Object last():
返回Set中最后一個(最高)元素。
(4).SortedSet subset(fromElement, toElement):
返回此Set中從fromElement(包括)到toElement(不包括)的子Set。
(5).SortedSet headset(toElement):
返回此Set中元素嚴格小于toElement的子Set。
(6).SortedSet tailSet(fromElement):
返回此Set中元素大于等于fromElement的子Set。
3.SortedMap是一個根據Key排序的Map,SortedMap接口有以下方法:
(1).Comparator comparator():
返回此Map中key進行排序的比較器,如果返回的是null,則該Map的key使用自然排序。
(2).T firstKey():
返回此Map中第一個(最低)key。
(3).T lastKey();
返回此Map中最后一個(最高)key。
(4).SortedMap subMap(fromKey, toKey):
返回此Map中key從fromKey(包括)到toKey(不包括)的子Map。
(5).SortedMap headMap(toKey):
返回此Map中key嚴格小于toKey的子Map。
(6).SortedMap tailMap(fromKey):
返回此Map中key大于等于fromKey的Map。
4.HashMap/HashSet等Hash算法集合重寫equals方法和hashCode方法:
HashSet,HashMap以及它們的子類等這些使用Hash算法的集合存放對象時,如果元素不是java中的8種基本類型(即元素都是對象類型),則必須重寫對象的equals和hashCode方法,否則會產生一些錯誤,例如:
[java]?view plaincopy輸出的結果是:false。
Map中有Key為A(1)對象,但是卻沒有找到,這是因為HashMap使用Hash算法根據對象的hashCode值來查找給定的對象,如果沒有重寫hashCode和equals方法,則對象默認使用Object的hashCode方法,Object默認hashCode方法使用對象的內存地址作為hashCode值。
為了使Hash算法集合存放對象類型數據符合用戶的期望,必須重寫對象的hashCode和equals方法,其中hashCode方法用于Hash算法的查找,equals方法用于對象比較,Hash算法中還要用到equals方法如下:
因為Hash算法所使用的hashCode可能會產生碰撞(不相等對象的hashCode值相同),當Hash算法產生碰撞時,就需要再次Hash(即再次通過其他方法計算hashCode值),所以一個對象使用Hash算法時,其對應的HashCode值可能不止一個,而是一組,當產生碰撞時就選擇另一個hashCode值。當hashCode值產生碰撞時,還必須使用equals方法方法對象是否相等。
注意:由于Hash算法有可能會產生碰撞(不相等的對象hashCode值相同),所以hashCode和equals方法有如下關系:
(1).equals方法相等的對象,hashCode方法值一定相同。
(2).hashCode方法相同的對象,equals不一定相等。
5.創建只讀集合容器:
List,Set和Map類型的集合容器都可以通過下面的方法創建為只讀,即只可以訪問,不能添加,刪除和修改。
[java]?view plaincopy(1).只讀集合:
[java]?view plaincopy(2).只讀List:
[java]?view plaincopy(3).只讀Set:
[java]?view plaincopy(4).只讀Map:
[java]?view plaincopy只讀集合容器會在編譯時檢查操作,如果對只讀集合容器進行增刪等操作時,將會拋出UnSupportedOperationException異常。
只讀集合容器類似于將集合對象訪問控制修飾符設置為private,不同之處在于,其他類可以訪問,只是不能修改。
6.線程同步集合容器:
Java集合容器中,Vector,HashTable等比較古老的集合容器是線程安全的,即處理了多線程同步問題。
而Java2之后對Vector和HashTable的替代類ArrayList,HashSet,HashMap等一些常用的集合容器都是非線程安全的,即沒有進行多線程同步處理。
Java中可以通過以下方法方便地將非線程安全的集合容器進行多線程同步:
(1).線程同步集合:
Collection<String> c= Collections.synchronizedCollection(newArrayList<String>());
(2).線程同步List:
List<String> c= Collections.synchronizedList(newArrayList<String>());
(3).線程同步Set:
Set<String> c= Collections.synchronizedSet(newHashSet<String>());
(4).線程同步Map:
Map<String> c= Collections.synchronizedMap(newHashMap<String, String>());
7.對象的強引用、軟引用、弱引用和虛引用:
JDK1.2以前版本中,只存在一種引用——正常引用,即對象強引用,如果一個對象被一個引用變量所指向,則該對象是可觸及(reached)的狀態,JVM垃圾回收器不會回收它,弱一個對象不被任何引用變量指向,則該對象就處于不可觸及的狀態,垃圾回收器就會回收它。
從JDK1.2版本之后,為了更靈活的控制對象生命周期,引入了四種引用:強引用(java.lang.ref.Reference)、軟引用(java.lang.ref.SoftReference)、弱引用(java.lang.ref.WeakReference)和虛引用(java.lang.ref.PhantomReference):
(1). 強引用(java.lang.ref.Reference):
??? 即Java程序中普遍使用的正常對象引用,存放在內存中得對象引用棧中,如果一個對象被強引用,則說明程序還在使用它,垃圾回收器不會回收,當內存不足時,JVM拋出內存溢出異常使程序異常終止。
(2). 軟引用(java.lang.ref.SoftReference):
如果一個對象只具有軟引用,則內存空間足夠,垃圾回收器也不會回收它;如果內存空間不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。軟引用可用來實現內存敏感的高速緩存。
軟引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果軟引用所引用的對象被垃圾回收器回收,JVM就會把這個軟引用加入到與之關聯的引用隊列中。
(3). 弱引用(java.lang.ref.WeakReference):
弱引用用來實現內存中對象的標準映射,即為了節約內存,對象的實例可以在一個程序內多處使用。
弱引用與軟引用的區別在于:只具有弱引用的對象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存。不過,由于垃圾回收器是一個優先級很低的后臺線程,因此不一定會很快發現那些只具有弱引用的對象。
弱引用也可以和一個引用隊列(ReferenceQueue)聯合使用,如果弱引用所引用的對象被垃圾回收,Java虛擬機就會把這個弱引用加入到與之關聯的引用隊列中。
(4). 虛引用(java.lang.ref.PhantomReference):
“虛引用”顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用并不會決定對象的生命周期。如果一個對象僅持有虛引用,那么它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。
虛引用主要用來跟蹤對象被垃圾回收器回收的活動。虛引用與軟引用和弱引用的一個區別在于:虛引用必須和引用隊列 (ReferenceQueue)聯合使用。當垃圾回收器準備回收一個對象時,如果發現它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之 關聯的引用隊列中。
ReferenceQueue queue =?new?ReferenceQueue ();
PhantomReference pr =?new?PhantomReference (object, queue);
?? JVM中,對象的引用往往都是很復雜的,各個對象之間相互引用形成一個內存引用樹,java中某個對象是否可觸及,有以下兩條判斷原則:
a.單條引用路徑可及性判斷:在這條路徑中,最弱的一個引用決定對象的可及性。
b.多條引用路徑可及性判斷:幾條路徑中,最強的一條的引用決定對象的可及性。
軟引用,弱引用,虛引用例子如下:
[java]?view plaincopy輸出結果為:
Just created:java.lang.ref.SoftReference@757aef
Just created:java.lang.ref.SoftReference@d9f9c3
Just created:java.lang.ref.WeakReference@9cab16
Just created:java.lang.ref.WeakReference@1a46e30
In queue: null
Finalizing Weak 0
Finalizing Weak
Finalizing Weak 1
Just created:java.lang.ref.PhantomReference@3e25a5
In queue: null
Just created:java.lang.ref.PhantomReference@19821f
注意:由于System.gc()只是通知JVM虛擬機可以進行垃圾回收器可以進行垃圾回收了,但是垃圾回收器具體什么時候允許說不清楚,所以這個輸出結果只是個參考,每次運行的結果Finalize方法的執行順序不太一樣。
從程序可以看出,盡管對象被引用,垃圾回收器還是回收了被引用對象,引用隊列總是創建一個包含null對象的引用。
8.WeakHashMap:
WeakHashMap專門用于存放弱引用,WeakHashMap很容易實現弱引用對象標準映射功能。
在WeakHashMap中,只存儲一份對象的實例及其值,當程序需要對象實例值時,WeakHashMap從現有的映射中找出已存在的對象值映射。
由于弱引用節約內存的技術,WeakHashMap允許垃圾回收器自動清除器存放的key和value。WeakHashMap自動將其中存放的key和value包裝為弱引用,當key不再被使用時,垃圾回收器自動回收該key和value。
總結
以上是生活随笔為你收集整理的《Java编程思想》学习笔记9——集合容器高级的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Java编程思想》学习笔记4——集合容
- 下一篇: JAVA线程池(ThreadPoolEx