HashSet源码分析

Set家族一览:

Set层次

HashSet简介

Set是Collection三大接口其中之一,意为集合,且元素不能重复。Set接口中的方法和Collection中的方法完全一致,只是起到一个标记名的作用。

HashSet是哈希集的意思,就是通过hashcode来实现set不能出现重复元素的一个实现类。

内部其实是通过哈希表HashMap来实现的,实际上set中存放的元素是内部hashmap中的键:

private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();//所有的键对应的值都是一个冗余的Object对象

在构造方法中初始化哈希表:

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

浪费时间警告:这是一个纯HashMap实现的类

重载的构造方法

public HashSet(Collection<? extends E> c)

通过一个集合来构造HashSet,默认哈希表的容量是集合的容量*4/3 + 116中的最大值

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)

这个实际上就是提供两个构造HashMap的参数,一个是初始大小,一个是负载因子。

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

public HashSet(int initialCapacity)

这个就是提供HashMap的初始大小。

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

重要方法

public int size()

HashMap的size

public int size() {
    return map.size();
}

public boolean contains(Object o)

HashMap中是否有对应的键。

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

public boolean add(E e)

将一个记录插入HashMap

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

public boolean remove(Object o)

public boolean remove(Object o) {
    return map.remove(o)==PRESENT;
}

总结

这是一个纯使用HashMap实现的数据结构。
仔细看了一下TreeSet也是用TreeMap实现的,那我就不搞TreeSet了。

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/hashset%e6%ba%90%e7%a0%81%e5%88%86%e6%9e%90/

(0)
彭晨涛彭晨涛管理者
上一篇 2019年11月29日 18:05
下一篇 2019年12月4日 18:05

相关推荐

  • try-catch-finally字节码实例探究

    本文使用Idea的jclasslib插件查看字节码。本文全程自言自语,请勿自行代入。 概述 java是怎么处理try-catch-finally的? 我们在深入理解java虚拟机第…

    2020年4月8日
    0720
  • HashMap源码分析

    HashMap是java中非常常见的一个数据结构,在这篇文章里,我依然以Map中的操作为导向来循序渐进研究HashMap中的源码,阅读这篇文章需要的前置知识有: 弱平衡的二叉查找树…

    Java 2020年2月12日
    0220
  • JDK8u20字符串去重

    优点:节省大量内存 缺点:略微多占用cpu时间,新生代回收时间略微增加 -XX:+UseStringDeduplication String s1 = new String("he…

    Java 2020年1月15日
    0740
  • ConcurrentHashMap源码分析

    ConcurrentHashMap的源码比较难读,特别是JDK8中几乎对其进行了重写,设计思想非常优秀,代码量也是非常多,不过我这里算是总结了一些相对重要的部分,仅供参考。 线程安…

    2020年2月13日
    0160
  • Java中的四种内部类

    我发现最近真是越来越没有东西写了。。。不可能天天学习新知识啊,最近在复习阶段了,复习的东西大多数是博客里写过的/(ㄒoㄒ)/ 复习Java基础的时候认真看了一下Java的内部类,这…

    Java 2020年5月23日
    0100
  • 常用开源数据库连接池C3P0、Druid介绍

    概述 很多时候,连接的混乱管理所造成的系统资源开销过大成为制约大型企业级应用效率的瓶颈。因为每一次WEB请求都要建立一次数据库连接,建立连接是一个耗费资源的活动,每次都得花费0.0…

  • Random在多线程下的问题以及ThreadLocalRandom类分析

    Ramdom在多线程环境下的问题 首先我们看一下Random类的nextInt源码: //产生[0,bound)的随机数 public int nextInt(int bound)…

    Java 2020年5月18日
    0540
  • Java线程池详解

    线程池就是享元模式和生产者消费者模式的应用 动手实现线程池 步骤1:自定义拒绝策略接口 @FunctionalInterface // 拒绝策略 interface RejectP…

    2020年2月3日
    0310
  • 深入理解java虚拟机第三版读书笔记09

    续深入理解java虚拟机第三版读书笔记08 类加载器 通过一个类的全限定名来获取描述该类的二进制字节流称为类加载器。类加载器可以用户自定义,是java语言流行的一项原因 类与类加载…

    2020年1月23日
    0130
  • 深入理解java虚拟机第三版读书笔记06

    附: Java虚拟机规范-Class文件格式:JDK8 Java虚拟机规范-Class文件格式:JDK13 以下是第六章 类文件结构的内容 Class类文件的结构 Class文件是…

    Java 2020年1月18日
    0170

发表回复

登录后才能评论