一.概述

  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. -WEBKIT-USER-SELECT:NONE导致输入框无法输入

    原文:http://hicc.me/post/webkit-user-select-none-disabling-text-field.html 最近在webview中写页面的时候发现个别Androi ...

  2. JAVA基础知识之数据类型

    JAVA的数据类型知识点主要包括基本数据类型,包装类,字符串类(String,StringBuffer, StringBuilder区别和用法),数组,数据类型转换等等,暂时只想到这么多,后面会再补充 ...

  3. Entity Framework 第二篇 事务

    Entity Framework  事务 结合第一篇的代码 public class BaseRepository : ITransaction, IDisposable { private XFDb ...

  4. CentOS 安装Redis

    redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcached类似,但很大程度补偿了memcached的不足,它支持存储的value类型相对更多,包括strin ...

  5. Java中的的XML文件读写

    XML简介 要理解XML,HTML等格式,先来理解文档对象模型DOM 根据 DOM,HTML 文档中的每个成分都是一个节点,这些节点组成了一棵树.DOM 是这样规定的:整个文档是一个文档节点每个 HT ...

  6. 实现的时钟(time)

    <!doctype html><html lang="en"><head> <script type="text/javascr ...

  7. winform应用程序自动更新版本

    http://blog.csdn.net/gxxloveszj/article/details/8278187 http://www.cnblogs.com/x369/articles/105656. ...

  8. update-alternatives命令

    快速复习: 增加:$sudo update-alternatives --install 程序生成的快捷方式的目标完整位置 程序名 程序其中一个版本的完整路径 配置:$sudo update-alte ...

  9. 2012 #3 Arcane Numbers

    Arcane Numbers 1 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Su ...

  10. 【Unity3D游戏开发】Application.systemLanguage无法区分简体中文和繁体中文 (二六)

    游戏发布,语言本地化需要繁体中文和简体中文 iOS8版本之前没问题,iOS9上无法正常识别这两种语言 原因是在iOS9上,Unity通过Application.systemLanguage返回的简体中 ...