三种常用Set:HashSet、LinkedHashSet、TreeSet

  set类继承关系:

    

  概述

    Set是对对应Map的一种封装,Set中的元素不可以重复。

    HashSet对应 HashMap、LInkedHashSet对应LinkedHashMap、TreeSet对应TreeMap

   HashSet特点

    1 不保证set的迭代顺序,特别是它不保证该顺序恒久不变;

    2 不允许有重复元素,这是因为HashSet是基于HashMap实现的,HashSet中的元素都存放在HashMap的key上面,而value中的值都是统一的一个private static final Object PRESENT = new Object();

    3 非线程安全的;

    4 HashSet通过iterator()返回的迭代器是fail-fast的(参考http://www.cnblogs.com/chenssy/p/3870107.html)。

  HashSet源码分析,LInkedHashSet和TreeSet类似

    成员变量

    两个重要的成员变量:map、PRESENT

    1)map:HashSet基于一个HashMap实现;

    2)PRESENT:作为HashMap中的value;

 public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L; private transient HashMap<E,Object> map;
//定义一个"虚拟"的static final Object对象作为HashMap的value
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

    构造函数

    //构造函数,即新建一个HashMap,默认初识容量为16,加载因子为0.75。
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
。。。

    查找

      HashSet提供了contains(Object o)查看是否包含指定元素的方法,其底层调用的是HashMap.containsKey(Object key)判断是否包含指定key。

     //Set是否含有元素o,即map中是否含有该key
public boolean contains(Object o) {
return map.containsKey(o);
}

    添加

      HashSet提供了add(E e)添加元素的方法,其调用的是底层HashMap中的put(K key, V value)方法,首先判断元素(也就是key)是否存在,如果不存在则插入,如果存在则不插入,这样HashSet中就不存在重复值。

    //如果此set中尚未包含指定元素,则添加指定元素
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

      底层:当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该值确定对象在HashSet中的存储位置。在HashSet中,不能同时存放两个相等的元素,而判断两个元素相等的标准是两个对象通过equals方法比较相等并且两个对象的HashCode方法返回值也相等。

      注意:对于HashSet中保存的对象,请注意正确重写其equals和hashCode方法,以保证放入的对象的唯一性。

    清空与删除

 //如果指定元素存在于此set中,则将其移除
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
} //从此set中移除所有元素
public void clear() {
map.clear();
}

    其他

     //返回此set中的元素的数量
public int size() {
return map.size();
} //如果此set不包含任何元素,则返回 true
public boolean isEmpty() {
return map.isEmpty();
} //返回此 HashSet实例的浅表副本
@SuppressWarnings("unchecked")
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(e);
}
}

    迭代器

     //返回对此 set中元素进行迭代的迭代器
public Iterator<E> iterator() {
return map.keySet().iterator(); //HashMap.keySet()返回<key, value>对中的key集
}

参考资料

https://www.cnblogs.com/CherishFX/p/4790735.html

最新文章

  1. 慕课网__HTML5 存储
  2. yii隐藏域的使用方法
  3. java 11-7String类里的方法的一些案例
  4. Centos 时间同步服务器
  5. The Stereo Action Dimension
  6. hdu 4911 Inversion (分治 归并排序 求逆序数)
  7. ASP.NET实现折线图的绘制
  8. C++:private继承与public继承
  9. MFC中控件的TAB顺序 ----转载
  10. Windows下使用ODBC API访问数据库之关键
  11. C# this关键字
  12. 使用WebBrowser控件时在网页元素上绘制文本或其他自定义内容
  13. 冒泡动画按钮的简单实现(使用CSS3)
  14. Hadoop完全分布式环境搭建
  15. iOS7动态调整文字大小
  16. I/O输出流基础之FileOutputStream
  17. top 命令常用操作
  18. js统计输入文字的字节数(byte)
  19. POJ 3126 --Father Christmas flymouse【scc缩点构图 &amp;amp;&amp;amp; SPFA求最长路】
  20. coding云(git)远程创建版本库和上传文件

热门文章

  1. win10搭建FTP服务器
  2. React报错 :browserHistory doesn&#39;t exist in react-router
  3. es6中的模版字符串
  4. 认识mysql(2)
  5. 三十五、MySQL 运算符
  6. L2TP用户添加和删除、搜索脚本
  7. tp3.2框架中使用volist输出混乱的一点发现
  8. kubernetes中使用ServiceAccount创建kubectl config 文件
  9. g++编译器的使用(转载)
  10. cut(树形DP)