在前篇博文(HashMap)中详细讲解了HashMap的实现过程,对于HashSet而言,它是基于HashMap来实现的,底层采用HashMap来保存元素。所以如果对HashMap比较熟悉,那么HashSet是so  easy!!

  

  HashSet继承AbstractSet类,实现Set、Cloneable、Serializable接口。其中AbstractSet提供 Set 接口的骨干实现,从而最大限度地减少了实现此接口所需的工作。Set接口是一种不包括重复元素的Collection,它维持它自己的内部排序,所以随机访问没有任何意义。

  基本属性

  //基于HashMap实现,底层使用HashMap保存所有元素

  private transient HashMap<E,Object> map;

  //定义一个Object对象作为HashMap的value

  private static final Object PRESENT = new Object();

  构造函数

  /**  默认构造函数

  * 初始化一个空的HashMap,并使用默认初始容量为16和加载因子0.75。

  */

  public HashSet() {

    map = new HashMap<>();

  }

  /** 构造一个包含指定 collection 中的元素的新 set。 */

  public HashSet(Collection<? extends E> c) {

    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));

    addAll(c);

  }

  /** 构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和指定的加载因子 */

  public HashSet(int initialCapacity, float loadFactor) {

    map = new HashMap<>(initialCapacity, loadFactor);

  }

  /**构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)。 */

  public HashSet(int initialCapacity) {

    map = new HashMap<>(initialCapacity);

  }

  /**在API中我没有看到这个构造函数,今天看源码才发现(原来访问权限为包权限,不对外公开的)

  * 以指定的initialCapacity和loadFactor构造一个新的空链接哈希集合。

  * dummy 为标识 该构造函数主要作用是对LinkedHashSet起到一个支持作用

  */

  HashSet(int initialCapacity, float loadFactor, boolean dummy) {

    map = new LinkedHashMap<>(initialCapacity, loadFactor);

  }

  从构造函数中可以看出HashSet所有的构造都是构造出一个新的HashMap,其中最后一个构造函数,为包访问权限是不对外公开,仅仅只在使用LinkedHashSet时才会发生作用。

  既然HashSet是基于HashMap,那么对于HashSet而言,其方法的实现过程是非常简单的。

  1.iterator()方法返回对此 set 中元素进行迭代的迭代器。返回元素的顺序并不是特定的。底层调用HashMap的keySet返回所有的key,这点反应了HashSet中的所有元素都是保存在HashMap的key中,value则是使用的PRESENT对象,该对象为static final。

  

  2.size()返回此 set 中的元素的数量(set 的容量)。底层调用HashMap的size方法,返回HashMap容器的大小。

  

   3. isEmpty(),判断HashSet()集合是否为空,为空返回 true,否则返回false

  

  4.contains(),判断某个元素是否存在于HashSet()中,存在返回true,否则返回false。更加确切的讲应该是要满足这种关系才能返回true:(o==null ? e==null : o.equals(e))。底层调用containsKey判断HashMap的key值是否为空。

  

  5. add()如果此 set 中尚未包含指定元素,则添加指定元素。如果此Set没有包含满足(e==null ? e2==null : e.equals(e2)) 的e2时,则将e2添加到Set中,否则不添加且返回false。由于底层使用HashMap的put方法将key = e,value=PRESENT构建成key-value键值对,当此e存在于HashMap的key中,则value将会覆盖原有value,但是key保持不变,所以如果将一个已经存在的e元素添加中HashSet中,新添加的元素是不会保存到HashMap中,所以这就满足了HashSet中元素不会重复的特性。

  

  6.remove如果指定元素存在于此 set 中,则将其移除。底层使用HashMap的remove方法删除指定的Entry。

  

  7.clear从此 set 中移除所有元素。底层调用HashMap的clear方法清除所有的Entry。

  

  8.clone返回此 HashSet 实例的浅表副本:并没有复制这些元素本身。

  

  后记:

    由于HashSet底层使用了HashMap实现,使其的实现过程变得非常简单,如果你对HashMap比较了解,那么HashSet简直是小菜一碟。有两个方法  对HashMap和HashSet而言是非常重要的,下篇将详细讲解hashcode和equals。

  以上内容均来自http://www.cnblogs.com/chenssy/博客,此博客为本人学习笔记

最新文章

  1. C#发送邮箱
  2. 某预约系统分析 &gt; 某区公共自行车租车卡在线预约,关于如何提高成功概率
  3. Windows7+VS2010下OpenGL的环境配置
  4. 浅谈mybatis中的#和$的区别
  5. 测试Swift语言代码高亮-使用highlight.js
  6. 如何在makefile中写cd命令
  7. Oracle与SQL Server事务处理的比较
  8. java springmvc Log4j filter等(稍微完善一下项目)
  9. Spring HTTP invoker 入门
  10. linux学习笔记之零散笔记。
  11. mahout源码分析之Decision Forest 三部曲之二BuildForest(1)
  12. jquery.form.js用法之清空form的方法
  13. XTU 1243 2016
  14. APP被苹果APPStore拒绝的各种原因
  15. 别纠结mybatis啦,赶紧来瞅瞅吧
  16. [C#]设计模式-单例模式-创建型模式
  17. SQL Server 分区表上建立ColumnStore Index 如何添加新分区方法与步骤
  18. HO6 Condo Insurance Policy
  19. Redisson碰到的问题
  20. Centos7找不到ifconfig和netstat命令

热门文章

  1. 十六进制颜色值和rgb颜色值互相转换
  2. 中间件weblogic控制台创建数据源报错---根据真实故事改编
  3. linux 时间和时区设置
  4. selenium:chromedriver与chrome版本对应关系
  5. springcloud-知识点总结(一):Eureka
  6. jQuery——检测滚动条是否到达底部
  7. 大数据入门到精通6---spark rdd reduce by key 的使用方法
  8. json and pickle 序列化
  9. matplotlib 坑
  10. Es6(Symbol,set,map,filter)