激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

香港云服务器
服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - Java 容器類(lèi)源碼詳解 Set

Java 容器類(lèi)源碼詳解 Set

2019-06-26 13:07Givefine Java教程

這篇文章主要介紹了Java 容器類(lèi)源碼詳解 Set,Set 表示由無(wú)重復(fù)對(duì)象組成的集合,也是集合框架中重要的一種集合類(lèi)型,直接擴(kuò)展自 Collection 接口。,需要的朋友可以參考下

前言

Set 表示由無(wú)重復(fù)對(duì)象組成的集合,也是集合框架中重要的一種集合類(lèi)型,直接擴(kuò)展自 Collection 接口。在一個(gè) Set 中,不能有兩個(gè)引用指向同一個(gè)對(duì)象,或兩個(gè)指向 null 的引用。如果對(duì)象 a 和 b 的引用滿(mǎn)足條件 a.equals(b),那么這兩個(gè)對(duì)象也不能同時(shí)出現(xiàn)在集合中。

通常 Set 是不要求元素有序的,但也有一些有序的實(shí)現(xiàn),如 SortedMap 接口、LinkedHashSet 接口等。

概述

Set 的具體實(shí)現(xiàn)通常都是基于 Map 的。因?yàn)?Map 中鍵是唯一的,因而在基于 Map 實(shí)現(xiàn) Set 時(shí),只需要關(guān)心 Map 中的鍵,和鍵關(guān)聯(lián)的值不需要有意義,使用一個(gè)任意的對(duì)象“占位”即可。我們?cè)谇懊娣治?Map 中的迭代器時(shí),KeySet() 方法得到的就是一個(gè) Set。

前面我們分析過(guò) Map 接口的幾個(gè)具體實(shí)現(xiàn),通用的實(shí)現(xiàn) HahsMap ,插入或訪問(wèn)序的 LinkedHashMap , 按照鍵升序的 TreeMap。同樣,在 Set 的具體實(shí)現(xiàn)中,也有 HashSet 、 LinkedHashSet 和 TreeSet 等,分別和 Map 一一對(duì)應(yīng),它們的特性對(duì)應(yīng)著相應(yīng)的 Map 實(shí)現(xiàn)的特性。下面基于 HashSet 的實(shí)現(xiàn)做一個(gè)簡(jiǎn)略的介紹。

HashSet 的實(shí)現(xiàn)

01public class HashSet<E>
02extends AbstractSet<E>
03implements Set<E>, Cloneable, java.io.Serializable
04{
05static final long serialVersionUID = -5024744406713321676L;
06private transient HashMap<E,Object> map;
07// Dummy value to associate with an Object in the backing Map
08private static final Object PRESENT = new Object();
09public HashSet() {
10map = new HashMap<>();
11}
12public HashSet(Collection<? extends E> c) {
13map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
14addAll(c);
15}
16public HashSet(int initialCapacity, float loadFactor) {
17map = new HashMap<>(initialCapacity, loadFactor);
18}
19public HashSet(int initialCapacity) {
20map = new HashMap<>(initialCapacity);
21}
22HashSet(int initialCapacity, float loadFactor, boolean dummy) {
23map = new LinkedHashMap<>(initialCapacity, loadFactor);
24}
25}


從成員變量和構(gòu)造方法可以清楚地看到,內(nèi)部使用了一個(gè) HahsMap,同時(shí)定義了一個(gè)無(wú)意義的空的靜態(tài) Object 對(duì)象(占用8byte) PRESENT。既然 map 中和鍵關(guān)聯(lián)的值沒(méi)有意義,為什么不干脆使用 null 呢?我們看一下 add() 方法:

1public boolean add(E e) {
2return map.put(e, PRESENT)==null;
3}

Map 的 put() 方法在添加一個(gè)新的鍵時(shí)會(huì)返回 null,在更新一個(gè)已經(jīng)存在的鍵關(guān)聯(lián)的值時(shí)會(huì)返回舊值。因而 Set 中的 add() 方法可以據(jù)此判斷新加入的元素是否改變了集合,如果改變了就返回 true。因而 PRESENT 不可以使用 null 。

其它的方法這里簡(jiǎn)單地列一下,都是基于 map 實(shí)現(xiàn)的:

01public boolean contains(Object o) {
02return map.containsKey(o);
03}
04public boolean remove(Object o) {
05return map.remove(o)==PRESENT;
06}
07public Iterator<E> iterator() {
08return map.keySet().iterator();
09}
10public int size() {
11return map.size();
12}
13public boolean isEmpty() {
14return map.isEmpty();
15}
16public void clear() {
17map.clear();
18}
19@SuppressWarnings("unchecked")
20public Object clone() {
21try {
22HashSet<E> newSet = (HashSet<E>) super.clone();
23newSet.map = (HashMap<E, Object>) map.clone();
24return newSet;
25} catch (CloneNotSupportedException e) {
26throw new InternalError(e);
27}
28}
29//序列化
30private void writeObject(java.io.ObjectOutputStream s)
31throws java.io.IOException {
32// Write out any hidden serialization magic
33s.defaultWriteObject();
34// Write out HashMap capacity and load factor
35s.writeInt(map.capacity());
36s.writeFloat(map.loadFactor());
37// Write out size
38s.writeInt(map.size());
39// Write out all elements in the proper order.
40for (E e : map.keySet())
41s.writeObject(e);
42}
43private void readObject(java.io.ObjectInputStream s)
44throws java.io.IOException, ClassNotFoundException {
45// Read in any hidden serialization magic
46s.defaultReadObject();
47 
48// Read capacity and verify non-negative.
49int capacity = s.readInt();
50if (capacity < 0) {
51throw new InvalidObjectException("Illegal capacity: " +
52capacity);
53}
54// Read load factor and verify positive and non NaN.
55float loadFactor = s.readFloat();
56if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
57throw new InvalidObjectException("Illegal load factor: " +
58loadFactor);
59}
60// Read size and verify non-negative.
61int size = s.readInt();
62if (size < 0) {
63throw new InvalidObjectException("Illegal size: " +
64size);
65}
66// Set the capacity according to the size and load factor ensuring that
67// the HashMap is at least 25% full but clamping to maximum capacity.
68capacity = (int) Math.min(size * Math.min(1 / loadFactor, 4.0f),
69HashMap.MAXIMUM_CAPACITY);
70// Create backing HashMap
71map = (((HashSet<?>)this) instanceof LinkedHashSet ?
72new LinkedHashMap<E,Object>(capacity, loadFactor) :
73new HashMap<E,Object>(capacity, loadFactor));
74// Read in all elements in the proper order.
75for (int i=0; i<size; i++) {
76@SuppressWarnings("unchecked")
77E e = (E) s.readObject();
78map.put(e, PRESENT);
79}
80}

小結(jié)

Set 的內(nèi)部通常是基于 Map 來(lái)實(shí)現(xiàn)的,Map 中的 Key 構(gòu)成了 Set,而 Value 全部使用一個(gè)無(wú)意義的 Object 。

Set 的特征與其內(nèi)部的 Set 的特征是一致的。基于 HashMap 的 HashSet 是無(wú)序時(shí)的最佳通用實(shí)現(xiàn),基于 LinkedHashMap 的 LinkedHashSet 保留插入或訪問(wèn)的順序,基于 TreeMap 的 TreeSet 可以按照元素升序排列,要求元素實(shí)現(xiàn) Comaprable 接口或自定義比較器。

HashSet , LinkedHashSet, TreeSet 都不是線程安全的,在多線程環(huán)境下使用時(shí)要注意同步問(wèn)題。

CopyOnWriteArraySet 是一個(gè)線程安全的實(shí)現(xiàn),但是并不是基于 Map 實(shí)現(xiàn)的,而是通過(guò) CopyOnWriteArrayList 實(shí)現(xiàn)的。使用 addIfAbsent() 方法進(jìn)行去重,性能比較一般。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

延伸 · 閱讀

精彩推薦
574
主站蜘蛛池模板: 看av网址 | 色妹子久久| 精品国产一区二区三区四区阿崩 | 国产91小视频在线观看 | 欧美特一级片 | 久久久www成人免费精品 | 黄色欧美精品 | 久久久精品综合 | 麻豆蜜桃在线观看 | 偿还电影免费看 | 91免费在线播放 | 欧美性猛交xxxxx按摩国内 | 91综合在线观看 | 在线成人一区二区 | 国产欧美精品一区二区三区四区 | 欧美日韩精品一区二区三区蜜桃 | www.99热视频| 狠狠婷婷综合久久久久久妖精 | 精品中文字幕久久久久四十五十骆 | 精品一区二区免费 | 欧美一级特黄a | 久久精品亚洲欧美日韩精品中文字幕 | 日韩视频在线观看免费 | 亚洲精品一区二区三区在线看 | 一级一级一级一级毛片 | 国产91在线高潮白浆在线观看 | 欧美在线黄色 | 国产精品午夜小视频观看 | 超碰97国产在线 | 九九热精品在线视频 | 日韩中文字幕一区二区三区 | 久久精品一区视频 | 51色视频| 国产88久久久国产精品免费二区 | 精品国产一区二区三区四区阿崩 | 国产精品久久77777 | 第四色成人网 | 草操视频 | 精品偷拍久久 | 中文字幕在线观看1 | 日韩一级免费毛片 |