Java集合篇:HashSet

Java集合篇:HashSet

对于HashSet而言,它是基于HashMap来实现的,底层采用HashMap来保存元素。HashSet存储元素的顺序并不是按照存入时的顺序,是按照哈希值来存的,所以取数据也是按照哈希值来取得。HashSet集合元素不能是Null。

一、定义:

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

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

1、基本属性:

//基于HashMap实现,底层使用HashMap保存所有元素
private transient HashMap<E,Object> map;
 
 //定义一个Object对象作为HashMap的value
 private static final Object PRESENT = new Object();

2、构造函数:

/**
         * 默认构造函数
         * 初始化一个空的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而言,其方法的实现过程是非常简单的。

public Iterator<E> iterator() {
        return map.keySet().iterator();
    }

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

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

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

public boolean isEmpty() {
        return map.isEmpty();
    }

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

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

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

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

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中元素不会重复的特性。

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

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

public void clear() {
        map.clear();
    }

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

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();
        }
    }

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/114664.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 大数据在农业应用_让脸变干净的小妙招

    大数据在农业应用_让脸变干净的小妙招民以食为天。互联网与农业深度融合,推动农业大数据发展。在互联网时代,通过大数据分析,让智慧农业发展更迅速。搭乘智慧农业快车,今后农业种地将不再是脏累差的工作,而会变得越来越简单、舒服,收益也会不断提高,体面高端的“新农人”职业一定会受到追捧。掘金农业大数据当前,“互联网+”已经上升为国家战略,成为发展的新增长点,是中央和地方政策扶持的重点,也是投资的焦点。在推进大众创业、万众创新中,“互联网+”呈…

    2022年10月5日
    6
  • internal server error原因及解决

    internal server error原因及解决常见的内部服务错误的原因有二,一是服务器资源紧张,二是文件权限错误。1.错误的原因一:服务器资源超载。服务器的资源超载:即同一时间内处理器有太多的进程需要处理的时候,会出现500错误。借助SSH,可

    2022年7月4日
    32
  • windowServer_windowsserver是什么

    windowServer_windowsserver是什么本文转载自https://msdn.microsoft.com/zh-cn/library/ff384253.aspx,主要内容是对msdn中对AppFabric介绍内容的整合以及一些自己的理解。简介AppFrabic托管功能解决的问题特性与功能体系结构IIS和WASASPNETWCF和WF运行时数据库暂留持久化托管承载监控监视管理APIIISManage托管功能应用

    2022年10月17日
    3
  • iOS导航栏基础效果配置[通俗易懂]

    iOS导航栏基础效果配置

    2022年4月3日
    48
  • github中删除项目

    github中删除项目

    2021年10月15日
    48
  • Netty框架的下载「建议收藏」

    1.Netty框架Jar包的下载:上图中标记的点都需要√上,并且文件夹的位置表示,会将下载好的Netty中的相关文件放在指定的目录下的lib文件夹下面。然后点击搜索,在下拉框中选择合适的版本进行下载…

    2022年4月11日
    55

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号