一.概述

  HashSet是建立在HashMap的基础上的,其内部存在指向一个HashMap对象的引用,操作HashSet实际上就是操作HashMap,而HashMap中所有键的值都指向一个叫做Dummy value的值.这是一个Object对象.是在HashSet进行显示初始化的时候初始化出来的,而HashMap在构造函数中被创建出来.
二.HashMap在HashSet方法中的使用及LinkedHashMap
  HashSet是建立在HashMap的基础上的,它的几乎所有的操作都是通过HashMap完成对于key的操作来实现的,通过add方法可以得知,这个HashMap所有的键都指向一个值.

public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
//存储键值对的Map.这个Map将不会被序列化
private transient HashMap<E,Object> map; // Dummy value
private static final Object PRESENT = new Object(); public HashSet() {
map = new HashMap<E,Object>();
} public HashSet(Collection<? extends E> c) {
map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
} public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<E,Object>(initialCapacity, loadFactor);
} public HashSet(int initialCapacity) {
map = new HashMap<E,Object>(initialCapacity);
}
//LinkedHashSet的实现关键
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
} public Iterator<E> iterator() {
return map.keySet().iterator();
} public int size() {
return map.size();
} public boolean isEmpty() {
return map.isEmpty();
} public boolean contains(Object o) {
return map.containsKey(o);
} public boolean add(E e) {
//放入元素和present的键值对
return map.put(e, PRESENT)==null;
} public boolean remove(Object o) {
return map.remove(o)==PRESENT;
} public void clear() {
map.clear();
}

  有两点需要注意的,第一点,这个Map是不会序列化的,因此在写入文件的时候,除了写入文件HashSet的信息以外,还写入map的容量(capacity),装填因子(loadFactor)以及元素数目(size),然后在从文件读取的时候,先创建map,然后依次从map中装填key的信息.代码如下:

private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
s.defaultWriteObject(); s.writeInt(map.capacity());
s.writeFloat(map.loadFactor()); s.writeInt(map.size()); for (Iterator i=map.keySet().iterator(); i.hasNext(); )
s.writeObject(i.next());
} private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject(); int capacity = s.readInt();
float loadFactor = s.readFloat();
map = (((HashSet)this) instanceof LinkedHashSet ?
new LinkedHashMap<E,Object>(capacity, loadFactor) :
new HashMap<E,Object>(capacity, loadFactor)); int size = s.readInt(); for (int i=0; i<size; i++) {
E e = (E) s.readObject();
map.put(e, PRESENT);
}
}

    第二点,HashSet中有一个不是公共的有boolean类型的参数的构造方法,它供LinkedHashSet调用.可以将LinkedHashSet内置的Map引用初始化为LinkedHashMap对象.(注意LinkedHashSet无法实现按照访问顺序排序).

Java源码初学_HashSet&LinkedHashSet的更多相关文章

  1. Java源码初学_AbstractList&AbstractCollection

    一.AbstractCollection抽象类:(提供了Collection接口的骨干实现,以减少实现接口所需要的工作) 1.contains方法 contains方法,通过迭代器对于列表的每一个元素 ...

  2. Java源码初学_LinkedHashMap

    一.概述: LinkedHashMap是HashMap的子类,它的基本操作与HashMap相同,与之不同的是,它可以实现按照插入顺序进行排序.也可以通过在构造函数中指定参数,按照访问顺序排序(Link ...

  3. Java源码初学_HashMap

    一.概念 HashMap的实例有两个参数影响其性能:初始容量和加载因子.容量是哈希表中桶的数量,初始容量只是哈希表在创建时的容量.加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度.当哈希表 ...

  4. Java源码初学_LinkedList

    一.LinkedList的内部数据结构 LinkedList底层是一个链表的数据结构,采用的是双向链表,基本的Node数据结构代码如下: private static class Node<E& ...

  5. Java源码初学_ArrayList

    一.ArrayList的构造器和构造方法 在ArrayList中定义了两个空数组,分别对应当指定默认构造方法时候,指向的数组已经给定容量,但是容量等于0的时候,指向的数组.此外在构造函数中传入Coll ...

  6. 【java集合框架源码剖析系列】java源码剖析之HashSet

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于HashSet的知识. 一HashSet的定义: public class HashSet&l ...

  7. 如何阅读Java源码 阅读java的真实体会

    刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心.   说到技术基础,我打个比 ...

  8. Android反编译(一)之反编译JAVA源码

    Android反编译(一) 之反编译JAVA源码 [目录] 1.工具 2.反编译步骤 3.实例 4.装X技巧 1.工具 1).dex反编译JAR工具  dex2jar   http://code.go ...

  9. 如何阅读Java源码

    刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动.源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 说到技术基础,我打个比方吧, ...

随机推荐

  1. 使用pt-heartbeat检测主从复制延迟

    不要用SECONDS_BEHIND_MASTER来衡量MYSQL主备的延迟时间,原因如下: A:备库Seconds_behand_master值是通过将服务器当前的时间戳与二进制日志中的事件的时间戳对 ...

  2. myeclipse 常用快捷键总结

    1 shift+enter 不管鼠标在当前行的什么位置,重新开启一行(向下) 2 shift+ctrl+enter 不管鼠标在当前行的什么位置,重新开启一行(向上) 3 Ctrl+D     删除一行 ...

  3. 如何在html添加一个搜索框和一个按钮?

    <INPUT TYPE="text" id="k"><INPUT TYPE="button" VALUE="ok ...

  4. R2D2 and Droid Army(多棵线段树)

    R2D2 and Droid Army time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  5. Uva 10118 免费糖果

    题目链接:https://uva.onlinejudge.org/external/101/10118.pdf 参考:http://www.cnblogs.com/kedebug/archive/20 ...

  6. Spring 中的页面重定向

    在写 java 程序设计实践作业的时候遇到了重定向页面的需求,因为还没学到 java web 开发,所以自己就在网上搜了一下相关的代码,总结出了一些小小的经验,希望在下学期学 java web 的时候 ...

  7. Jquery中的filter()详细说明和transition的用法

    filter() 方法将匹配元素集合缩减为匹配指定选择器的元素. 详细说明 如果给定表示 DOM 元素集合的 jQuery 对象,.filter() 方法会用匹配元素的子集构造一个新的 jQuery ...

  8. 越狱后如何添加cydia源及cydia源大全

    http://jingyan.baidu.com/article/6c67b1d6cc53fe2787bb1e06.html 软件游戏能PJ,插件其实也一样,所以有些源里面就包含了大量的PJ插件~ a ...

  9. Easyui部分组件讲解

    Easyui部分组件讲解 目  录 1.... Accordion(可折叠标签)... 2 1.1          实例... 2 1.2          参数... 3 2.... DateBo ...

  10. 未完成的任务之:下载、安装、体验 Gentoo

    Gentoo,伟大的Gentoo是Linux世界最年轻的发行版本,正因为年轻,所以能吸取在她之前的所有发行版本的优点,这也是Gentoo被称为最完美的Linux发行版本的原因之一. 如果你需要一个桌面 ...