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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • C#的WinForm窗体程序中如何设置TextBox为密码文本框

    C#的WinForm窗体程序中如何设置TextBox为密码文本框C#的WinForm窗体程序中如何设置TextBox为密码文本框-2019-08-0323:59在C#的WinForm窗体程序开发过程中,TextBox是常用的文本框控件,默认的TextBox

    2022年7月1日
    20
  • vs2010旗舰版_密钥

    vs2010旗舰版_密钥YCFHQ-9DWCY-DKV88-T2TMH-G7BHP

    2022年5月3日
    42
  • 网页设计实现留言板_有关留言板界面的设计

    网页设计实现留言板_有关留言板界面的设计web网页设计期末大作业_留言板制作.doc本科学生综合性实验报告姓名___李朝彭__学号_______1341004242___学院________信息学院_专业软件工程班级_13F_课程名称《Web应用开发技术》实验名称综合性作品设计—留言板_指导教师_______白磊_______________开课学期2014至2…

    2025年6月25日
    2
  • 大佬,到底什么是Java的反射?

    大佬,到底什么是Java的反射?什么是反射 JAVA 反射机制是在运行状态中 对于任何一个类 都能够知道这个类的所有属性和方法 对于任何一个对象 都能够调用它的任意方法和属性 这种动态获取信息以及动态调用对象方法的功能称为 java 语言的反射机制一般情况下 我们使用类来创建对象都是一开始就知道具体的类型以及类的用途 直接通过类来创建对象 Orderorder newOrder newBigDecima 4 32 order getPrice 而反射是一开始不知道我需要初始化的类是什么 到实际运行的时候才知道具体的类

    2025年10月7日
    3
  • 赵青-《剑侠情缘网络版》开发回顾

    赵青-《剑侠情缘网络版》开发回顾赵青-《剑侠情缘网络版》开发回顾 赵青-《剑侠情缘网络版》开发回顾,(转自剑网1,作者应该是原剑网3技术总监)这篇文章首发于一本谈游戏研发的杂志,是赵青写的,写得非常不错。《剑侠情缘网络版》开发回顾2003年的1月,我刚刚开发完《天王》项目,正在休息、总结和规划下一个项目。《天王》是我开发的众多项目中最满意的一个,虽然这篇文字主要是对《剑侠…

    2022年7月19日
    13
  • javascript高级程序设计第四版pdf百度网盘_js高级程序设计第四版 pdf下载

    javascript高级程序设计第四版pdf百度网盘_js高级程序设计第四版 pdf下载需要的请私信.涉及版权无法直接上传

    2022年8月20日
    8

发表回复

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

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