基本介绍

  1. 1. 不允许重复(底层是HashMap,用key储存元素,value统一都是 PRESENT),可以为null,无顺序
  2. 2. HashSet就是为了提高查找效率的(在查找是否存在某个值时,ArrayList需要遍历才能确定某个值的位置,而HashSet可以通过HashCode快速定位)

源码分析

  1. public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable {
  2. static final long serialVersionUID = -5024744406713321676L;
  3. //底层是HashMap
  4. private transient HashMap<E,Object> map;
  5. //定义一个虚拟的Object对象作为HashMap的value,将此对象定义为static final。
  6. private static final Object PRESENT = new Object();
  7. public HashSet() {
  8. map = new HashMap<>();
  9. }
  10. public HashSet(Collection<? extends E> c) {
  11. map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
  12. addAll(c);
  13. }
  14. public HashSet(int initialCapacity, float loadFactor) {
  15. map = new HashMap<>(initialCapacity, loadFactor);
  16. }
  17. public HashSet(int initialCapacity) {
  18. map = new HashMap<>(initialCapacity);
  19. }
  20. //底层实际调用底层HashMap的keySet来返回所有的key
  21. public Iterator<E> iterator() {
  22. return map.keySet().iterator();
  23. }
  24. public int size() {
  25. return map.size();
  26. }
  27. public boolean isEmpty() {
  28. return map.isEmpty();
  29. }
  30. public boolean contains(Object o) {
  31. return map.containsKey(o);
  32. }
  33. //如果向HashSet中添加一个已经存在的元素时,新添加的集合元素将不会被放入HashMap中,
  34. //原来的元素也不会有任何改变,这也就满足了Set中元素不重复的特性
  35. public boolean add(E e) {
  36. return map.put(e, PRESENT)==null;
  37. }
  38. public boolean remove(Object o) {
  39. return map.remove(o)==PRESENT;
  40. }
  41. public void clear() {
  42. map.clear();
  43. }
  44. @SuppressWarnings("unchecked")
  45. public Object clone() {
  46. try {
  47. HashSet<E> newSet = (HashSet<E>) super.clone();
  48. newSet.map = (HashMap<E, Object>) map.clone();
  49. return newSet;
  50. } catch (CloneNotSupportedException e) {
  51. throw new InternalError(e);
  52. }
  53. }
  54. private void writeObject(java.io.ObjectOutputStream s)
  55. throws java.io.IOException {
  56. // Write out any hidden serialization magic
  57. s.defaultWriteObject();
  58. // Write out HashMap capacity and load factor
  59. s.writeInt(map.capacity());
  60. s.writeFloat(map.loadFactor());
  61. // Write out size
  62. s.writeInt(map.size());
  63. // Write out all elements in the proper order.
  64. for (E e : map.keySet())
  65. s.writeObject(e);
  66. }
  67. private void readObject(java.io.ObjectInputStream s)
  68. throws java.io.IOException, ClassNotFoundException {
  69. // Read in any hidden serialization magic
  70. s.defaultReadObject();
  71. // Read capacity and verify non-negative.
  72. int capacity = s.readInt();
  73. if (capacity < 0) {
  74. throw new InvalidObjectException("Illegal capacity: " +
  75. capacity);
  76. }
  77. // Read load factor and verify positive and non NaN.
  78. float loadFactor = s.readFloat();
  79. if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
  80. throw new InvalidObjectException("Illegal load factor: " +
  81. loadFactor);
  82. }
  83. // Read size and verify non-negative.
  84. int size = s.readInt();
  85. if (size < 0) {
  86. throw new InvalidObjectException("Illegal size: " +
  87. size);
  88. }
  89. // Set the capacity according to the size and load factor ensuring that
  90. // the HashMap is at least 25% full but clamping to maximum capacity.
  91. capacity = (int) Math.min(size * Math.min(1 / loadFactor, 4.0f),
  92. HashMap.MAXIMUM_CAPACITY);
  93. // Constructing the backing map will lazily create an array when the first element is
  94. // added, so check it before construction. Call HashMap.tableSizeFor to compute the
  95. // actual allocation size. Check Map.Entry[].class since it's the nearest public type to
  96. // what is actually created.
  97. SharedSecrets.getJavaObjectInputStreamAccess()
  98. .checkArray(s, Map.Entry[].class, HashMap.tableSizeFor(capacity));
  99. // Create backing HashMap
  100. map = (((HashSet<?>)this) instanceof LinkedHashSet ?
  101. new LinkedHashMap<>(capacity, loadFactor) :
  102. new HashMap<>(capacity, loadFactor));
  103. // Read in all elements in the proper order.
  104. for (int i=0; i<size; i++) {
  105. @SuppressWarnings("unchecked")
  106. E e = (E) s.readObject();
  107. map.put(e, PRESENT);
  108. }
  109. }
  110. }

HashSet 详解的更多相关文章

  1. Java 容器之Hashset 详解

    Java 容器之Hashset 详解.http://blog.csdn.net/nvd11/article/details/27716511

  2. java中HashSet详解(转)

    HashSet 的实现 对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSe ...

  3. java中HashSet详解

    HashSet 的实现 对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSe ...

  4. java集合(4)- java中HashSet详解

    HashSet 的实现 对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSe ...

  5. java集合HashMap、HashTable、HashSet详解

    一.Set和Map关系 Set代表集合元素无序,集合元素不可重复的集合,Map代表一种由多个key-value组成的集合,map集合是set集合的扩展只是名称不同,对应如下 二.HashMap的工作原 ...

  6. 35 、HashSet详解

    HashSet特点 1.不能保证元素的排列顺序 2.没有重复元素 3.HashSet不是同步的,多个线程同时访问一个HashSet,需要通过代码来保持同步 4.集合元素可以是null 当向HashSe ...

  7. Java集合详解7:一文搞清楚HashSet,TreeSet与LinkedHashSet的异同

    <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...

  8. 集合框架的详解,List(ArrayList,LinkedList,Vector),Set(HashSet,TreeSet)-(14)

    集合详解: /* Collection |--List:元素是有序的,元素可以重复.因为该集合体系有索引. |--ArrayList:底层的数据结构使用的是数组结构.特点:查询速度很快.但是增删稍慢. ...

  9. Code First开发系列之管理数据库创建,填充种子数据以及LINQ操作详解

    返回<8天掌握EF的Code First开发>总目录 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LINQ to ...

随机推荐

  1. 使用openntpd替换ntpd

    系统自带的ntp服务太难用,systemd启动几次没启动起来,懒得折腾,换了openntpd一次成功.

  2. Oracle数据库中文乱码问题解决

    1.查看服务器端编码select userenv('language') from dual;我实际查到的结果为:AMERICAN_AMERICA.ZHS16GBK 2.执行语句 select * f ...

  3. 【leetcode】965. Univalued Binary Tree

    题目如下: A binary tree is univalued if every node in the tree has the same value. Return true if and on ...

  4. idea 增量包配置

    set CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,serve ...

  5. jquery基础知识实例(一)

    轮滑 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.o ...

  6. Shiro学习(6)Realm整合

    6.1 Realm [2.5 Realm]及[3.5 Authorizer]部分都已经详细介绍过Realm了,接下来再来看一下一般真实环境下的Realm如何实现. 1.定义实体及关系 即用户-角色之间 ...

  7. mysql怎样更改密码和用户名

    mysql怎样更改密码和用户名 更改密码(老版本): mysql -u root -p Enter password:*** mysql>use mysql; --选择数据库-- Databas ...

  8. 改变IntelliJ IDEA 中的system和config/plugins的默认C盘的路径

    1,问题,在为idea在线安装插件时,如JProfiler,会默认安装到C盘,而本人则是希望安装到软件所在的D盘目录下,那么如何修改呢: C:\Users\xxx\.IntelliJIdea\conf ...

  9. LeetCode 分隔链表

    题目链接:https://leetcode-cn.com/problems/partition-list/ 题目大意 略. 分析 空间复杂度 O(1) 的做法蛮有意思的,另外加头结点可以少写很多代码. ...

  10. 1029 Median (25 分)

    1029 Median (25 分)   Given an increasing sequence S of N integers, the median is the number at the m ...