文档章节

【java集合框架源码剖析系列】java源码剖析之HashSet

htq
 htq
发布于 2016/07/26 09:41
字数 872
阅读 4
收藏 0

注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本。本博客将从源码角度带领大家学习关于HashSet的知识。

一HashSet的定义:

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
可以看到HashSet继承自AbstractSet同时实现了Set,Cloneable,Serializable三个接口,其中Cloneable,Serializable这两个接口基本上是java集合框架中所有的集合类都要实现的接口。

二HashSet中的重要属性:

<strong>  </strong>private transient HashMap<E,Object> map;
  private static final Object PRESENT = new Object();
可以看到HashSet中的属性非常少,其中第一个属性是HashMap对象,是HashSet中用来存储数据的,据此可知HashSet的底层是基于HashMap的,关于HashMap的详细讲解请参看我的博客: 【java集合框架源码剖析系列】java源码剖析之HashMap,而第二个属性表示的是HashSet中HashMap实例的value,因为HashSet虽然底层是基于HashMap实现的,但是HashSet只用来存储Key,其Value是无意义,Value的值全部用第二个属性代替。

三HashSet内部的实现原理:我们来看一下其构造器

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

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

public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }

 public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

 HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }
可以看到HashSet供5个构造器,其中前四个都是在其内部创建一个HashMap的实例,(从这里更清楚的看到HashSet的底层是基于HashMap的)而第5个则是创建一个LinkedHashMap的实例,而且第5个构造器前面无public修饰,表明该构造器对外不公开,事实上仅仅供LinkedHashSet使用的。第二个构造器表明当使用一个集合c作为参数来构造一个HashSet的时候会调用addAll(c),我们来看一下其源码:

public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }

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

可以看到在addAll中调用了add(),而在add(E)方法中可以清楚看到使用HashMap的put方法时第二个参数传入的都是PRESENT,这就说明了HashSet中只保存Key而不保存Value。

四HashSet中的重要方法:

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();
    }
可以看到HashSet中与HashMap中同名的方法全部都是调用的HashMap中的方法来实现的。

五总结:经过前面HashMap的源码剖析可以看到HashSet非常简单

1HashSet底层是基于HashMap的,但是仅仅用来保存Key,而不保存Value,因为HashSet的add()方法在调用HashMap的put方法的时候第二个参数传入的都是PRESENT这个固定的Object对象。

2可以看到HashSet中的add与remove等方法均无synchronized关键字修饰,即HashSet不是线程安全的,如果要使用同步的HashSet需要使用Collections集合类的静态方法,即Set s=Collections.synchronizedSet(new HashSet());

3HashSet中的值允许为null,因为HashSet底层是基于HashMap的,而HashMap允许插入null。

4HashSet中的元素不允许重复,因为HashSet底层是基于HashMap的,而HashMap不允许存在重复元素,因为在put时如果key相同则会替换之前的V值。

本文转载自:http://blog.csdn.net/htq__/article/details/51056462

共有 人打赏支持
htq

htq

粉丝 19
博文 67
码字总数 1007
作品 3
武汉
私信 提问
Android--面试中遇到的问题总结(三)

《Android 开发工程师面试指南 LearningNotes 》,作者是陶程,由梁观全贡献部分。大家可以去知乎关注这两位用心的少年。这份指南包含了大部分Android开发的基础、进阶知识,不仅可以帮助准备...

sealin
2017/02/22
0
0
一份关于 Java、Kotlin 与 Android 的学习笔记

JavaKotlinAndroidLearn 这是一份关于 Java 、Kotlin 、Android 的学习笔记,既包含对基础知识点的介绍,也包含对一些重要知识点的源码解析,笔记的大纲如下所示: Java 重拾Java(0)-基础知...

叶应是叶
08/08
0
0
Java开发者不会这些永远都只能是三流程序员,细数一下你是不是?

源码系列 手写spring mvc框架 基于Spring JDBC手写ORM框架 实现自己的MyBatis Spring AOP实战之源码分析 Spring IOC高级特性应用分析 ORM框架底层实现原理剖析 手写Spring MVC框架实现 手把手...

美的让人心动
04/16
0
0
三流程序员与一流程序员之间的区别,看看你是属于哪一类?

源码系列 手写spring mvc框架 基于Spring JDBC手写ORM框架 实现自己的MyBatis Spring AOP实战之源码分析 Spring IOC高级特性应用分析 ORM框架底层实现原理剖析 手写Spring MVC框架实现 手把手...

茶轴的青春
04/17
0
0
Jodd 3.4.2 发布,常用 Java 工具包

Jodd 3.4.2 版本最大改动就是全新的 HTTP 客户端,另外该版本最终改用了 Gradle,包含了 ASM 4.1 源码,增加了 BeanCopy 工具,移除过时的编译器包,JDateTime 增加了 Period 类,Madvoc 提供...

oschina
2013/02/25
4.1K
12

没有更多内容

加载失败,请刷新页面

加载更多

20181213 上课截图

小丑鱼00
11分钟前
0
0
nginx+php-fpm配置后页面显示空白的解决方法以及用nginx和php-fpm解决“502 Bad Gateway”问题

https://stackoverflow.com/questions/15423500/nginx-showing-blank-php-pages For reference, I am attaching my location block for catching files with the .php extension: location ~......

Yao--靠自己
19分钟前
1
0
mac 没声音

somehow不时就会出现这种情况。之前都得重启。 其实可以直接在terminal里打以下命令: sudo kextunload /System/Library/Extensions/AppleHDA.kext sudo kextload /System/Library/Extension...

dubox
34分钟前
1
0
看完让你彻底搞懂Websocket原理

作者:Ovear 链接:https://www.zhihu.com/question/20215561/answer/40316953 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 额。。最高票答案没答到点...

时刻在奔跑
49分钟前
2
0
Spring Cloud Stream消费失败后的处理策略(一):自动重试

之前写了几篇关于Spring Cloud Stream使用中的常见问题,比如: 如何处理消息重复消费 如何消费自己生产的消息 下面几天就集中来详细聊聊,当消息消费失败之后该如何处理的几种方式。不过不论...

程序猿DD
51分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部