java hashset 源码_Java 集合系列16之 HashSet详细介绍(源码解析)和使用示例

1 packagejava.util;2

3 public class HashSet

4 extends AbstractSet

5 implements Set, Cloneable, java.io.Serializable6 {7 static final long serialVersionUID = -5024744406713321676L;8

9 //HashSet是通过map(HashMap对象)保存内容的

10 private transient HashMapmap;11

12 //PRESENT是向map中插入key-value对应的value13 //因为HashSet中只需要用到key,而HashMap是key-value键值对;14 //所以,向map中添加键值对时,键值对的值固定是PRESENT

15 private static final Object PRESENT = newObject();16

17 //默认构造函数

18 publicHashSet() {19 //调用HashMap的默认构造函数,创建map

20 map = new HashMap();21 }22

23 //带集合的构造函数

24 public HashSet(Collection extends E>c) {25 //创建map。26 //为什么要调用Math.max((int) (c.size()/.75f) + 1, 16),从 (c.size()/.75f) + 1 和 16 中选择一个比较大的树呢?27 //首先,说明(c.size()/.75f) + 128 //因为从HashMap的效率(时间成本和空间成本)考虑,HashMap的加载因子是0.75。29 //当HashMap的“阈值”(阈值=HashMap总的大小*加载因子) < “HashMap实际大小”时,30 //就需要将HashMap的容量翻倍。31 //所以,(c.size()/.75f) + 1 计算出来的正好是总的空间大小。32 //接下来,说明为什么是 16 。33 //HashMap的总的大小,必须是2的指数倍。若创建HashMap时,指定的大小不是2的指数倍;34 //HashMap的构造函数中也会重新计算,找出比“指定大小”大的最小的2的指数倍的数。35 //所以,这里指定为16是从性能考虑。避免重复计算。

36 map = new HashMap(Math.max((int) (c.size()/.75f) + 1, 16));37 //将集合(c)中的全部元素添加到HashSet中

38 addAll(c);39 }40

41 //指定HashSet初始容量和加载因子的构造函数

42 public HashSet(int initialCapacity, floatloadFactor) {43 map = new HashMap(initialCapacity, loadFactor);44 }45

46 //指定HashSet初始容量的构造函数

47 public HashSet(intinitialCapacity) {48 map = new HashMap(initialCapacity);49 }50

51 HashSet(int initialCapacity, float loadFactor, booleandummy) {52 map = new LinkedHashMap(initialCapacity, loadFactor);53 }54

55 //返回HashSet的迭代器

56 public Iteratoriterator() {57 //实际上返回的是HashMap的“key集合的迭代器”

58 returnmap.keySet().iterator();59 }60

61 public intsize() {62 returnmap.size();63 }64

65 public booleanisEmpty() {66 returnmap.isEmpty();67 }68

69 public booleancontains(Object o) {70 returnmap.containsKey(o);71 }72

73 //将元素(e)添加到HashSet中

74 public booleanadd(E e) {75 return map.put(e, PRESENT)==null;76 }77

78 //删除HashSet中的元素(o)

79 public booleanremove(Object o) {80 return map.remove(o)==PRESENT;81 }82

83 public voidclear() {84 map.clear();85 }86

87 //克隆一个HashSet,并返回Object对象

88 publicObject clone() {89 try{90 HashSet newSet = (HashSet) super.clone();91 newSet.map = (HashMap) map.clone();92 returnnewSet;93 } catch(CloneNotSupportedException e) {94 throw newInternalError();95 }96 }97

98 //java.io.Serializable的写入函数99 //将HashSet的“总的容量,加载因子,实际容量,所有的元素”都写入到输出流中

100 private voidwriteObject(java.io.ObjectOutputStream s)101 throwsjava.io.IOException {102 //Write out any hidden serialization magic

103 s.defaultWriteObject();104

105 //Write out HashMap capacity and load factor

106 s.writeInt(map.capacity());107 s.writeFloat(map.loadFactor());108

109 //Write out size

110 s.writeInt(map.size());111

112 //Write out all elements in the proper order.

113 for (Iterator i=map.keySet().iterator(); i.hasNext(); )114 s.writeObject(i.next());115 }116

117

118 //java.io.Serializable的读取函数119 //将HashSet的“总的容量,加载因子,实际容量,所有的元素”依次读出

120 private voidreadObject(java.io.ObjectInputStream s)121 throwsjava.io.IOException, ClassNotFoundException {122 //Read in any hidden serialization magic

123 s.defaultReadObject();124

125 //Read in HashMap capacity and load factor and create backing HashMap

126 int capacity =s.readInt();127 float loadFactor =s.readFloat();128 map = (((HashSet)this) instanceof LinkedHashSet ?

129 new LinkedHashMap(capacity, loadFactor) :130 new HashMap(capacity, loadFactor));131

132 //Read in size

133 int size =s.readInt();134

135 //Read in all elements in the proper order.

136 for (int i=0; i

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值