一.概述

  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. 关于android中Bundle的使用

      1.Android using Bundle for sharing variables 注:android中使用Bundle来共享变量,下例中Activity1和Activity2通过bundl ...

  2. 【20160924】GOCVHelper MFC增强算法(5)

    CString ExportListToExcel(CString  sExcelFile,CListCtrl* pList, CString strTitle)     {         CStr ...

  3. h264

    H264--编码原理以及I帧B帧P帧--1 前言 ----------------------- H264是新一代的编码标准,以高压缩高质量和支持多种网络的流媒体传输著称,在编码方面,我理解的他的理论 ...

  4. hiho 第1周 最长回文子串

    题目链接:http://hihocoder.com/problemset/problem/1032 #include <bits/stdc++.h> using namespace std ...

  5. Uva(10048),最短路Floyd

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  6. Poj(1466),最大独立集,匈牙利算法

    题目链接:http://poj.org/problem?id=1466 Girls and Boys Time Limit: 5000MS   Memory Limit: 10000K Total S ...

  7. Java中通过JDBC远程连接Oracle数据库

    通过jdbc连接数据库,拢共分三步: 第一步:下载一个JDBC的驱动,然后把jar包扔到项目里并add to build path: 第二步:去本地oracle文件夹下找到“TNSNAMES.ORA” ...

  8. ExecutorService - 10个技巧和窍门

    ExecutorService已经成为Java并发编程中常用的基础库,几乎所有到线程 任务等执行都要委托ExecutorService.下面是使用过程中10个技巧和窍门. 1.为线程池和线程取名 当我 ...

  9. sqlserver2008安装教程

    这几天因为需要,一直想安装sql server 2008来作为Web后台的数据库进行些实验,但总是没有时间,今天终于有时间了,便安装了SQL Server 2008,以下是我的安装的步骤,希望对于有需 ...

  10. java提高篇---Vector

    对于List接口这里还介绍一个它的实现类Vector,Vector 类可以实现可增长的对象数组. 一.Vector简介 Vector可以实现可增长的对象数组.与数组一样,它包含可以使用整数索引进行访问 ...