zoukankan      html  css  js  c++  java
  • 四.HashSet原理及实现学习总结

    在上一篇博文(HashMap原理及实现学习总结)详细总结了HashMap的实现过程,对于HashSet而言,它是基于HashMap来实现的,底层采用HashMap来保存元素。所以如果对HashMap比较熟悉,那么HashSet的原理应该很好理解!

    一.HsahSet概述

    HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用null元素。

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

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

    1 // 底层使用HashMap来保存HashSet中所有元素。
    2     private transient HashMap<E, Object> map;
    3 
    4     // 定义一个虚拟的Object对象作为HashMap的value,将此对象定义为static final。
    5     private static final Object PRESENT = new Object();

    构造函数: 
    从构造函数中可以看出HashSet所有的构造都是构造出一个新的HashMap,其中最后一个构造函数,为包访问权限是不对外公开,仅仅只在使用LinkedHashSet时才会发生作用。

    二.HsahSet实现

    因为HashSet是基于HashMap,所以对于HashSet,其方法的实现过程是非常简单的。 
    1. iterator() 
    iterator()方法 返回对此set中元素进行迭代的迭代器。返回元素的顺序并不是特定的。底层实际调用底层HashMap的keySet来返回所有的key。 可见HashSet中的元素,只是存放在了底层HashMap的key上, value使用一个static final的Object对象标识。

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

    2.size() 
    返回此set中的元素的数量(set的容量)。底层实际调用HashMap的size()方法返回Entry的数量,就得到该Set中元素的个数,即HashMap容器的大小。

    1 public int size() {
    2         return map.size();
    3     }

    3.isEmpty() 
    isEmpty()判断HashSet()集合是否为空,如果此set不包含任何元素,则返回true。 底层实际调用HashMap的isEmpty()判断该HashSet是否为空。

    1 public boolean isEmpty() {
    2         return map.isEmpty();
    3     }

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

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

    5.add() 
    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中元素不会重复的特性。

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

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

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

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

    1 public void clear() {
    2         map.clear();
    3     }

    8.clone() 
    底层实际调用HashMap的clone()方法,获取HashMap的浅表副本,并没有复制这些元素本身。

    1 public Object clone() {
    2         try {
    3             HashSet<E> newSet = (HashSet<E>) super.clone();
    4             newSet.map = (HashMap<E, Object>) map.clone();
    5             return newSet;
    6         } catch (CloneNotSupportedException e) {
    7             throw new InternalError();
    8         }
    9     }

    转载链接:http://blog.csdn.net/jianyuerensheng/article/details/51580688

  • 相关阅读:
    DIY 作品 及 维修 不定时更新
    置顶,博客中所有源码 github
    openwrt PandoraBox PBR-M1 极路由4 HC5962 更新固件
    使用 squid 共享 虚拟专用网至局域网
    第一次参加日语能力测试 N5
    libx264 libfdk_aac 编码 解码 详解
    开发RTSP 直播软件 H264 AAC 编码 live555 ffmpeg
    MFC Camera 摄像头预览 拍照
    http2 技术整理 nginx 搭建 http2 wireshark 抓包分析 server push 服务端推送
    plist 图集 php 批量提取 PS 一个个切
  • 原文地址:https://www.cnblogs.com/midiyu/p/8127562.html
Copyright © 2011-2022 走看看