jdk源码分析(六)——HashSet


我们在jdk源码分析(四)——ArrayListjdk源码分析(五)——HashMap中分别分析了List和Map两种数据结构,在Java的集合框架中,还有另一类成员,就是Set,今天我们就来看看常用的HashSet

一.类定义

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable

可以看到,和HashMap类似,HashSet也是继承了一个抽象类,并实现了一个基础的接口Set

Set接口中的主要方法如下:

核心的方法都是一些对集合的操作,例如添加元素,判断元素是否存在,遍历,删除等。

二.存储结构

HashSet主要是使用HashMap来实现元素的存储的:

// 存储集合元素
private transient HashMap<E,Object> map;
// 常量,表示某个集合元素存在,在map中作为value
private static final Object PRESENT = new Object();

因此主要操作都是围绕着这个map进行的,自然不可避免的要使用到我们上一篇中讲到的HashMap了。mapvalueObject类型的常量。

三.常用方法

1.构造方法

先来看看无参构造方法:

public HashSet() {
    map = new HashMap<E,Object>();
}

代码很简单,只有一行,完成对map的实例化,以备使用。

除了无参构造方法外,还可以基于已有的集合类来初始化HashMap

public HashSet(Collection<? extends E> c) {
    map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
    addAll(c);
}

首先调用了HashMap的构造方法,并指定map的初始容量。初始容量的计算方法如下:
(1)将集合中的元素个数除以0.75,向上取整
(2)取(1)中结果与16中的较大者
通过HashMap的源码分析,我们已经知道,HashMap的默认装载因子是0.75(也就是说,默认只装载75%左右的位置),而HashSet底层使用HashMap来存储,因此需要根据这个装载因子算出需要的散列表大小。而HashMap的默认大小是16,因此这里的初始化大小最小是16。

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

逻辑实现也很简单,就是调用HashMapput方法,将需要存储的集合元素作为key,将常量PRESENT作为value。put方法的返回值是map中与此key关联的value值,某个元素第一次存入时返回null,如果key已经存在,则返回此key对应的value。

需要注意的是,HashMap是允许key覆盖的,而集合Set的特性决定了,Set中同一个元素只能存在一次,因此,如果集合中已经存在该元素了,那么map的返回值为非null,从而add方法返回false。

3.contains方法
public boolean contains(Object o) {
    return map.containsKey(o);
}

该方法也比较简单,直接调用HashMapcontainsKey方法来判断元素是否存在。

HashSet的实现比较容易理解,我们就不再啰嗦了,轻松加愉快。期待与大家一起学习后面的jdk源码。

本文已迁移至我的博客:http://ipenge.com/54585.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、基本数据类型 注释 单行注释:// 区域注释:/* */ 文档注释:/** */ 数值 对于byte类型而言...
    龙猫小爷阅读 4,288评论 0 16
  • 实际上,HashSet 和 HashMap 之间有很多相似之处,对于 HashSet 而言,系统采用 Hash 算...
    曹振华阅读 2,526评论 1 37
  • java笔记第一天 == 和 equals ==比较的比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量...
    jmychou阅读 1,518评论 0 3
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,765评论 18 399
  • HashMap 是 Java 面试必考的知识点,面试官从这个小知识点就可以了解我们对 Java 基础的掌握程度。网...
    野狗子嗷嗷嗷阅读 6,705评论 9 107