一,Set之HashSet(转:http://blog.csdn.net/zheng0518/article/details/42197337)

1.    HashSet概述:

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

2.    HashSet的实现:

对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,因此HashSet 的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成, HashSet的源代码如下:

public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L; // 底层使用HashMap来保存HashSet中所有元素。
private transient HashMap<E,Object> map; // 定义一个虚拟的Object对象作为HashMap的value,将此对象定义为static final。
private static final Object PRESENT = new Object(); /**
* 默认的无参构造器,构造一个空的HashSet。
*
* 实际底层会初始化一个空的HashMap,并使用默认初始容量为16和加载因子0.75。
*/
public HashSet() {
map = new HashMap<E,Object>();
} /**
* 构造一个包含指定collection中的元素的新set。
*
* 实际底层使用默认的加载因子0.75和足以包含指定
* collection中所有元素的初始容量来创建一个HashMap。
* @param c 其中的元素将存放在此set中的collection。
*/
public HashSet(Collection<? extends E> c) {
map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
} /**
* 以指定的initialCapacity和loadFactor构造一个空的HashSet。
*
* 实际底层以相应的参数构造一个空的HashMap。
* @param initialCapacity 初始容量。
* @param loadFactor 加载因子。
*/
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<E,Object>(initialCapacity, loadFactor);
} /**
* 以指定的initialCapacity构造一个空的HashSet。
*
* 实际底层以相应的参数及加载因子loadFactor为0.75构造一个空的HashMap。
* @param initialCapacity 初始容量。
*/
public HashSet(int initialCapacity) {
map = new HashMap<E,Object>(initialCapacity);
} /**
* 以指定的initialCapacity和loadFactor构造一个新的空链接哈希集合。
* 此构造函数为包访问权限,不对外公开,实际只是是对LinkedHashSet的支持。
*
* 实际底层会以指定的参数构造一个空LinkedHashMap实例来实现。
* @param initialCapacity 初始容量。
* @param loadFactor 加载因子。
* @param dummy 标记。
*/
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
} /**
* 返回对此set中元素进行迭代的迭代器。返回元素的顺序并不是特定的。
*
* 底层实际调用底层HashMap的keySet来返回所有的key。
* 可见HashSet中的元素,只是存放在了底层HashMap的key上,
* value使用一个static final的Object对象标识。
* @return 对此set中元素进行迭代的Iterator。
*/
public Iterator<E> iterator() {
return map.keySet().iterator();
} /**
* 返回此set中的元素的数量(set的容量)。
*
* 底层实际调用HashMap的size()方法返回Entry的数量,就得到该Set中元素的个数。
* @return 此set中的元素的数量(set的容量)。
*/
public int size() {
return map.size();
} /**
* 如果此set不包含任何元素,则返回true。
*
* 底层实际调用HashMap的isEmpty()判断该HashSet是否为空。
* @return 如果此set不包含任何元素,则返回true。
*/
public boolean isEmpty() {
return map.isEmpty();
} /**
* 如果此set包含指定元素,则返回true。
* 更确切地讲,当且仅当此set包含一个满足(o==null ? e==null : o.equals(e))
* 的e元素时,返回true。
*
* 底层实际调用HashMap的containsKey判断是否包含指定key。
* @param o 在此set中的存在已得到测试的元素。
* @return 如果此set包含指定元素,则返回true。
*/
public boolean contains(Object o) {
return map.containsKey(o);
} /**
* 如果此set中尚未包含指定元素,则添加指定元素。
* 更确切地讲,如果此 set 没有包含满足(e==null ? e2==null : e.equals(e2))
* 的元素e2,则向此set 添加指定的元素e。
* 如果此set已包含该元素,则该调用不更改set并返回false。
*
* 底层实际将将该元素作为key放入HashMap。
* 由于HashMap的put()方法添加key-value对时,当新放入HashMap的Entry中key
* 与集合中原有Entry的key相同(hashCode()返回值相等,通过equals比较也返回true),
* 新添加的Entry的value会将覆盖原来Entry的value,但key不会有任何改变,
* 因此如果向HashSet中添加一个已经存在的元素时,新添加的集合元素将不会被放入HashMap中,
* 原来的元素也不会有任何改变,这也就满足了Set中元素不重复的特性。
* @param e 将添加到此set中的元素。
* @return 如果此set尚未包含指定元素,则返回true。
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
} /**
* 如果指定元素存在于此set中,则将其移除。
* 更确切地讲,如果此set包含一个满足(o==null ? e==null : o.equals(e))的元素e,
* 则将其移除。如果此set已包含该元素,则返回true
* (或者:如果此set因调用而发生更改,则返回true)。(一旦调用返回,则此set不再包含该元素)。
*
* 底层实际调用HashMap的remove方法删除指定Entry。
* @param o 如果存在于此set中则需要将其移除的对象。
* @return 如果set包含指定元素,则返回true。
*/
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
} /**
* 从此set中移除所有元素。此调用返回后,该set将为空。
*
* 底层实际调用HashMap的clear方法清空Entry中所有元素。
*/
public void clear() {
map.clear();
} /**
* 返回此HashSet实例的浅表副本:并没有复制这些元素本身。
*
* 底层实际调用HashMap的clone()方法,获取HashMap的浅表副本,并设置到HashSet中。
*/
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();
}
}
}

二,Set之LinkedHashSet

1.    LinkedHashSet概述:

LinkedHashSet是具有可预知迭代顺序的Set接口的哈希表和链接列表实现。此实现与HashSet的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可为插入顺序或是访问顺序。

注意,此实现不是同步的。如果多个线程同时访问链接的哈希Set,而其中至少一个线程修改了该Set,则它必须保持外部同步。

2.    LinkedHashSet的实现:

对于LinkedHashSet而言,它继承与HashSet、又基于LinkedHashMap来实现的。

LinkedHashSet底层使用LinkedHashMap来保存所有元素,它继承与HashSet,其所有的方法操作上又与HashSet相同,因此LinkedHashSet 的实现上非常简单,只提供了四个构造方法,并通过传递一个标识参数,调用父类的构造器,底层构造一个LinkedHashMap来实现,在相关操作上与父类HashSet的操作相同,直接调用父类HashSet的方法即可。LinkedHashSet的源代码如下:

public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable { private static final long serialVersionUID = -2851667679971038690L; /**
* 构造一个带有指定初始容量和加载因子的新空链接哈希set。
*
* 底层会调用父类的构造方法,构造一个有指定初始容量和加载因子的LinkedHashMap实例。
* @param initialCapacity 初始容量。
* @param loadFactor 加载因子。
*/
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
} /**
* 构造一个带指定初始容量和默认加载因子0.75的新空链接哈希set。
*
* 底层会调用父类的构造方法,构造一个带指定初始容量和默认加载因子0.75的LinkedHashMap实例。
* @param initialCapacity 初始容量。
*/
public LinkedHashSet(int initialCapacity) {
super(initialCapacity, .75f, true);
} /**
* 构造一个带默认初始容量16和加载因子0.75的新空链接哈希set。
*
* 底层会调用父类的构造方法,构造一个带默认初始容量16和加载因子0.75的LinkedHashMap实例。
*/
public LinkedHashSet() {
super(16, .75f, true);
} /**
* 构造一个与指定collection中的元素相同的新链接哈希set。
*
* 底层会调用父类的构造方法,构造一个足以包含指定collection
* 中所有元素的初始容量和加载因子为0.75的LinkedHashMap实例。
* @param c 其中的元素将存放在此set中的collection。
*/
public LinkedHashSet(Collection<? extends E> c) {
super(Math.max(2*c.size(), 11), .75f, true);
addAll(c);
}
}

重新开始学习javase_集合_Set的更多相关文章

  1. 重新开始学习javase_集合_Map

    一,Map之HashMap(转:http://blog.csdn.net/zheng0518/article/details/42197049) 1.    HashMap概述: HashMap是基于 ...

  2. 重新开始学习javase_集合_List

    一,List之ArrayList(转:http://blog.csdn.net/zheng0518/article/details/42198205) 1. ArrayList概述: ArrayLis ...

  3. 【新手向】如何学习Java集合

    前言 只有光头才能变强. 文本已收录至我的GitHub精选文章,欢迎Star:https://github.com/ZhongFuCheng3y/3y 如果认识我的同学可能就知道,我已经写过很多系列级 ...

  4. 重新开始学习javase_一切都是对象

    @学习thinking in java 一,一切都是对象 用句柄操纵对象 每种编程语言都有自己的数据处理方式.比如说c与c++中的指针,而java中尽管将一切都“看作”对象,但操纵的标识符实际是指向一 ...

  5. JavaSE_ 集合框架 总目录(15~18)

    JavaSE学习总结第15天_集合框架1 15.01 对象数组的概述和使用15.02 对象数组的内存图解15.03 集合的由来及与数组的区别15.04 集合的继承体系图解15.05 Collectio ...

  6. 学习:java集合

    java是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaEE, JavaME, Jav ...

  7. Python大神成长之路: 第三次学习记录 集合 函数 装饰 re

    学习记录day03   字符串可以直接切片,But字符串不可修改 字符串修改:生成了一个新的字符串 LIst修改,在原基础上修改(原内存上)     集合是一个无序的,不重复的数据组合,它的主要作用如 ...

  8. java工具类学习整理——集合

    好久没有总结一些东西了,同时集合部分的知识点也学习的比较早了,但是从来没有抽时间去研究和学习,今天正好有时间就总结一下map常用的遍历方法: package runningwhile; import ...

  9. Python学习之==>集合

    1.简介 集合也是一种数据类型,一个类似列表东西,它的特点是无序的,不重复的,也就是说集合中是没有重复数据的. 2.集合的作用 它可以把一个列表中重复的数据去掉,而不需要你再写判断 可以做关系测试,比 ...

随机推荐

  1. build Intent

    Intent用于activity之间, fragmetn之间, 或者APP间通信, 主要包含数据和Action两部分: 常见的action是字符串形式的activity指定 Intent intent ...

  2. 【HDOJ】2425 Hiking Trip

    优先级队列+BFS. #include <iostream> #include <cstdio> #include <cstring> #include <q ...

  3. Unity C# 游戏间物体间的访问

    脚本语言:C# 1.在Unity工程中新建两个物体:Cube和Sphere 2.分别为Cube和Sphere添加脚本CubeScript和SphereScript: 在SphereScript这两个定 ...

  4. bzoj1005

    有了bzoj1430的经验解决这题就不是什么难事了首先考虑度数确定的点,令tot=sigma(d[i]-1)首先给这tot个数分配prufer编码的位置有C(tot,n-2)种方案每个方案中是可以进行 ...

  5. Qt入门(20)——Qt模块简介

    当你安装Qt时,这些模块会被构建到库中.在Qt企业版.Qt评估版和Qt自由版中,包含所有的模块.对于Qt专业版,提供基本的模块--工具.核心.窗口部件.对话框.图标视图和工作区模块.画布模块画布模块提 ...

  6. 【模拟】Codeforces 710B Optimal Point on a Line

    题目链接: http://codeforces.com/problemset/problem/710/B 题目大意: 给N个点的坐标,在X轴上找到最靠左的点使得这个点到N个点距离之和最小. 题目思路: ...

  7. [转载]值得推荐的C/C++框架和库

    值得学习的C语言开源项目 C++ 资源大全 值得学习的C语言开源项目 1.Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我 ...

  8. 【行业干货】ASOS:外来快时尚品牌的入华战 - 行业干货 - 京东内部论坛 - Powered by Discuz!

    [行业干货]ASOS:外来快时尚品牌的入华战 - 行业干货 - 京东内部论坛 - Powered by Discuz! [行业干货]ASOS:外来快时尚品牌的入华战

  9. 专注于个人服装定做_服装设计_Fabric_Design_Tailor-迦勒定制网

    专注于个人服装定做_服装设计_Fabric_Design_Tailor-迦勒定制网 客服热线:400-720-7206 工作时间:AM 09:00-PM 10:00 周六/周日/节假日:设计师休息

  10. D - How Many Answers Are Wrong(hdu 3038)

    总算碰到一道不那么无聊的题了^^ 先说一下题意吧,有两个人一个叫TT的男孩一个叫FF的女孩(名字太随意了吧....),这个叫TT的男孩会经常叫这个女孩一起玩一个游戏,这个有些是这样的,随便写一个数列, ...