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

一.HsahSet概述

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

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

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

 // 底层使用HashMap来保存HashSet中所有元素。
private transient HashMap<E, Object> map; // 定义一个虚拟的Object对象作为HashMap的value,将此对象定义为static final。
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对象标识。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新文章

  1. nginx简易教程
  2. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(三)
  3. Struts2-----面试题汇总
  4. vim中多标签和多窗口的使用
  5. sublime text3 配置插件包记录
  6. 关于Android与pc通信时中文乱码的分析和解决
  7. asp.net 给按钮 增加事件
  8. Json.Net6.0
  9. a++与 ++a
  10. 【C#复习总结】垃圾回收机制(GC)1
  11. java 打印水仙花数
  12. M100 (0)开发
  13. shell中脚本变量和函数变量的作用域
  14. Structrued Streaming业务数据实时分析
  15. 阿里云liunx-ubuntu安装中文
  16. oracle多表查询之内连接,外连接语句总结
  17. Java之集合(二十二)PriorityBlockingQueue
  18. 分块+lazy 或者 线段树+lazy Codeforces Round #254 (Div. 2) E
  19. 裁剪TOGAF进行产品架构开发
  20. sql server将字符串转换为 uniqueidentifier 时失败

热门文章

  1. css颜色表示法
  2. python实用脚本集
  3. 第一次使用cisco packet tracer
  4. Ubuntu 18.04 安装微信(Linux通用)
  5. MySQL数据库的基本使用简单易懂
  6. WebService学习总结(一)——WebService的相关概念
  7. A1147. Heaps
  8. Mysql 远程连接服务器
  9. 自制模态窗体闪烁效果: MessageBeep &amp; FlashWindowEx
  10. bash 5