HashSet源码粗略解析
来源:互联网 发布:java开发月薪 编辑:程序博客网 时间:2024/06/05 05:11
复习下java的常用集合框架,java常用的集合大致有两种类型,一种实现了Collection接口表示普通的集合,一种实现了Map接口表示严格的键值对,其中Collection又分为List接口类型和Set接口类型,其中List接口类型允许集合中元素重复,例如ArrayList,Vector,LinkedList,Stack,Set接口实现的集合不允许重复元素,例如HashSet和TreeSet。
HashSet从类名就可以看出,它使用HashMap的存储方法存储元素,其中也就使用了HashMap的key那一部分,value默认为Object,所以它的元素不会重复。
package java.util;public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable{ static final long serialVersionUID = -5024744406713321676L;//存储元素的内部集合 private transient HashMap<E,Object> map; //因为它只需要保存不重复的key元素,value元素默认为一个Object就好 private static final Object PRESENT = new Object(); /** * 无参构造函数,默认的容量16,加载因子为3/4 */ public HashSet() { map = new HashMap<E,Object>(); } /** * 略,Math.max是求最大值,找到一个容量的参数,要么是c集合已有个数除以0.75,要么是16 */ public HashSet(Collection<? extends E> c) { map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } /** * 略 */ public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<E,Object>(initialCapacity, loadFactor); } /** * 略 */ public HashSet(int initialCapacity) { map = new HashMap<E,Object>(initialCapacity); } /** * 参考了他人的说法: 以指定的initialCapacity和loadFactor构造一个新的空链接哈希集合。 * 此构造函数为包访问权限,不对外公开,实际只是是对LinkedHashSet的支持。 * 实际底层会以指定的参数构造一个空LinkedHashMap实例来实现。 */ HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor); } /** * 返回迭代器,使用的键Set视图集合返回的迭代器 */ public Iterator<E> iterator() { return map.keySet().iterator(); } /** *返回有多少个元素 */ public int size() { return map.size(); } /** * 判断是否为空 */ public boolean isEmpty() { return map.isEmpty(); } /** * 包含 */ public boolean contains(Object o) { return map.containsKey(o); } /** * 增加一个元素,增加在key的位置上 */ public boolean add(E e) { return map.put(e, PRESENT)==null; } /** * 删除 */ public boolean remove(Object o) { return map.remove(o)==PRESENT; } /** * 删除所有 */ public void clear() { map.clear(); } /** * 克隆,调用的底层克隆方法 */ public Object clone() { try { HashSet<E> newSet = (HashSet<E>) super.clone(); newSet.map = (HashMap<E, Object>) map.clone(); return newSet; } catch (CloneNotSupportedException e) { throw new InternalError(); } } /** * Save the state of this <tt>HashSet</tt> instance to a stream (that is, * serialize it). * * @serialData The capacity of the backing <tt>HashMap</tt> instance * (int), and its load factor (float) are emitted, followed by * the size of the set (the number of elements it contains) * (int), followed by all of its elements (each an Object) in * no particular order. */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out any hidden serialization magic s.defaultWriteObject(); // Write out HashMap capacity and load factor s.writeInt(map.capacity()); s.writeFloat(map.loadFactor()); // Write out size s.writeInt(map.size()); // Write out all elements in the proper order. for (Iterator i=map.keySet().iterator(); i.hasNext(); ) s.writeObject(i.next()); } /** * Reconstitute the <tt>HashSet</tt> instance from a stream (that is, * deserialize it). */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in any hidden serialization magic s.defaultReadObject(); // Read in HashMap capacity and load factor and create backing HashMap int capacity = s.readInt(); float loadFactor = s.readFloat(); map = (((HashSet)this) instanceof LinkedHashSet ? new LinkedHashMap<E,Object>(capacity, loadFactor) : new HashMap<E,Object>(capacity, loadFactor)); // Read in size int size = s.readInt(); // Read in all elements in the proper order. for (int i=0; i<size; i++) { E e = (E) s.readObject(); map.put(e, PRESENT); } }}
可以看出HashSet非常简单,非线程安全,向HashMap一样没有容量限制
0 0
- HashSet源码粗略解析
- Hashtable源码粗略解析
- hashset 源码解析
- HashSet源码解析
- HashSet源码解析
- Java HashSet源码解析
- HashSet源码解析
- HashSet类源码解析
- 源码解析-集合-HashSet
- HashSet源码解析
- HashSet源码解析
- HashSet源码解析
- HashSet<T> 源码解析
- c#HashSet源码解析
- Set之HashSet源码解析
- JDK之Hashset源码解析
- java.util.HashSet源码解析
- JDK源码解析之HashSet
- 2016"百度之星" - 测试赛 1004 放盘子(水)
- 【线段树】浅谈区间问题(2)
- 【内外网映射】通过外网ip来访问虚拟机服务器【原创】
- Codeforces 667C Reberland Linguistics 【dp】
- 数据可视化中需要注意的问题
- HashSet源码粗略解析
- android工程eclipse转移至android studio中的问题
- JAVA环境变量配置和常用DOS命令
- 105_Volley源码解析
- all-delete-orphan
- [转]读研or工作--阿里巴巴吴翰清的邮件[技术性内容, 慎入]
- Faster RCNN blob.py
- 《UNIX环境高级编程》(system)
- Java与Oracle中日期转换