Java集合(六):专用集合和遗留类
本文是《Java核心技術 卷1》中第13章的讀書總結。
Java集合類庫中除了前面幾節(jié)中介紹的8個類之外,還有6個專用集與專用映射表,4個Java一開始就存在的類。這節(jié)將簡單介紹一下這些集合類。
1 弱散列映射表:WeakHashMap
WeakHashMap類是為了解決一個有趣的問題。如果有一個值,對應的鍵已經不再使用了,將會出現(xiàn)什么情況呢?假定對某個鍵的最后一次引用已經消亡,不再有任何途徑引用這個值的對象了。但是,由于程序中的任何部分沒有再出現(xiàn)這個鍵,所以這個鍵值對無法從映射表中刪除。為什么垃圾回收器不能刪除它呢?難道刪除無用的對象不是垃圾回收器的工作么?
遺憾的是,事情沒有這么簡單。垃圾回收器跟蹤活動的對象。只要映射表對象是活動的,其中的所有桶也是活動的,它們不能被回收。因此,需要由程序負責從長期存活的映射表中刪除無用的值。或者使用WeakHashMap完成這件事。當對鍵的唯一引用來自散列表條目時,這一數(shù)據(jù)結構將與垃圾回收器協(xié)調工作一起刪除鍵值對。
下面是這個機制的內部運行情況。WeakHashMap使用弱引用(weak reference)保存鍵。WeakReference對象將引用保存到另外一個對象中,在這里,就是散列表鍵。對于這種類型的對象,垃圾回收器用一種特有的方式進行處理。通常,如果垃圾回收器發(fā)現(xiàn)某個特定的對象已經沒有他人引用了,就將其收回。然而,如果某個對象這能由WeakReference引用,垃圾回收器仍然回收它,但要將引用這個對象的弱引用放入隊列中。WeakHashMap將周期性的檢查隊列,以便找出新添加的弱引用。一個弱引用進入隊列意味著這個鍵不再被他人使用,并且已經被收集起來。于是,WeakHashMap將刪除對應的條目。
2 鏈接散列集和鏈接映射表
Java SE 1.4 增加了兩個類:LinkedHashSet和LinkedHashMap,用來記住插入元素的順序。這樣就可以避免在散列表中的項從表面上看是隨機排列的。當條目插入到表中時,就會并入到雙向鏈表中。如下圖:
鏈接散列映射表將用訪問順序,而不是插入順序對映射表元素進行迭代。每次調用get或put,受到影響的元素將從當前位置刪除,并放到元素鏈表的尾部(只有元素在鏈表中的位置受影響,而散列表中的桶不會受影響。一個元素總位于與鍵散列碼對應的桶中)。
3 枚舉集與映射表
EnumSet是一個枚舉類型元素集的高效實現(xiàn)。由于枚舉類型只有有限個實例,所以EnumSet內部用位序列實現(xiàn)。如果對應的值在集中,則相應的位被置為1.
EnumSet類沒有公共的構造器,可以使用靜態(tài)工廠方法構造這個集:
enum Weekday={MONDAY,TUESDAY,WEDNESDAY,THURISDAY,FRIDAY,SATURDAY,SUNDAY}; EnumSet<Weekday> always=EnumSet.allOf(Weekday.class); EnumSet<Weekday> never=EnumSet.noneOf(Weekday.class); EnumSet<Weekday> workday=EnumSet.range(Weekday.MONDAY,Weekday.FRIDAY); EnumSet<Weekday> mwf=EnumSet.of(Weekday.MONDAY,Weekday.WEDNESDAY,Weekday.FRIDAY);可以使用Set接口的常用方法來修改EnumSet。EnumMap是一個鍵類型為枚舉類型的映射表。它可以直接且高效的用一個值數(shù)組實現(xiàn)。在使用時,需要在構造器中指定鍵類型:
EnumMap<Weekday,Employee> personInCharge=new EnumMap<>(Weekday.class);4 標識散列映射表:IdentityHashMap
Java SE 1.4 中還增加了一個特殊的類IdentityHashMap。在這個類中,鍵的散列值不是用hashCode方法計算的,而是用System.identityHashCode方法計算的。這是Object.hashCode方法根據(jù)對象的內存地址來計算散列碼時所使用的方式。而且,在對兩個對象進行比較時,IdentityHashMap類使用==,而不是equals。
也就是說,不同的鍵對象,即使內容相同,也被視為不同的對象。在實現(xiàn)對象遍歷算法(如對象序列化)時,這個類非常有用,可以用來跟蹤每個對象的遍歷狀況。
以上就是Java集合類庫中的專用集合類。接下來的是Java集合類庫中的遺留類。
5 Hashtable類
Hashtable和HashMap類的作用一樣,實際上,這兩個類擁有相同的接口。與Vector類一樣,Hashtable的方法也是同步的,這是與HashMap不同的地方。如果對同步性或與遺留代碼的兼容性沒有任何要求,就應該使用HashMap。
6 Enumeration接口
遺留集合使用Enumeration接口對元素進行遍歷。Enumeration接口有兩個方法,即hashMoreElements和nextElement。這兩個方法與Iterator接口的hashNext和next方法十分類似。
例如,Hashtable類的elements方法將產生一個用于描述表中各個枚舉值的對象:
Enumeration<Employee> e=staff.elements(); while(e.hasMoreElements()) {Employee em=e.nextElements();... }7 屬性映射表:Properties
Properties類是一個屬性映射表,是一個非常特殊的映射表結構。它有下面三個特性:
- 鍵與值都是字符串;
- 表可以保存到一個文件中,也可以從文件中加載;
- 使用一個默認的輔助表。
屬性映射表通常用于程序的特殊配置選項。
8 位集:BitSet
BitSet類用于存放一個位序列。如果需要高效的存儲位序列(比如標志)就可以使用BitSet。由于位集包裝在字節(jié)里,所以使用位集要比使用Boolean對象的ArrayList更加高效。
BitSet類提供了一個便于讀取、設置或清除各個位的接口。使用這個接口可以避免屏蔽和其它麻煩的位操作。如果將這些位存儲在int或long變量中就必須進行這些繁瑣的操作。
例如,對于一個名為bucketOfBits的BitSet:
bucketOfBits.get(i);如果第i位處于“開”的狀態(tài),就返回true,否則返回false。同樣:
bucketOfBits.set(i);將第i位設置為“開”狀態(tài)。最后: bucketOfBits.clear(i);將第i位置為“關”狀態(tài)。
9 棧:Stack
從1.0版開始,標準類庫中就包含了Stack類,其中有熟悉的push和pop操作。但是,Stack類擴展為Vector類,從理論角度看,Vector類并不令人滿意,它可以讓棧使用不屬于棧操作的insert和remove方法,即可以在任何地方進行插入或刪除操作,而不僅僅是棧頂。
總結
以上是生活随笔為你收集整理的Java集合(六):专用集合和遗留类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 再一次初恋剧情介绍
- 下一篇: 战地2042游戏闪退怎么办