集合番@HashSet一文通(1.7版)


[关闭]
@kiraSally
2017-07-21 11:38
字数 2244
阅读 7

HashSet一文通

JAVA COLLECTIONS 源码

1.什么是HashSet

  • 底层采用HashMap保存元素
  • 非重,无序,非同步
  • 本版本基于JDK1.7

2.HashSet的数据结构

  • 类定义
   
 
  1. public class HashSet<E>
  2. extends AbstractSet<E>
  3. implements Set<E>, Cloneable, java.io.Serializable
  • 重要全局变量
   
 
  1. //维护一个HashMap作为底层数据结构
  2. private transient HashMap<E,Object> map;
  3. //Dummy value, HashSet存储时,将该值作为底层map的默认value
  4. private static final Object PRESENT = new Object();
  • 构造器
   
 
  1. /**
  2. * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
  3. * default initial capacity (16) and load factor (0.75).
  4. */
  5. public HashSet() {
  6. map = new HashMap<>();
  7. }
  8. /**
  9. * 构造一个包含指定collection中的元素的新set。
  10. * 实际底层使用默认的加载因子0.75和足以包含指定collection中所有元素的初始容量来创建一个HashMap。
  11. * @param c 其中的元素将存放在此set中的collection。
  12. */
  13. public HashSet(Collection<? extends E> c) {
  14. map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
  15. addAll(c);
  16. }
  17. /**
  18. * 以指定的initialCapacity和loadFactor构造一个空的HashSet。
  19. * 实际底层以相应的参数构造一个空的HashMap。
  20. * @param initialCapacity 初始容量。
  21. * @param loadFactor 加载因子。
  22. */
  23. public HashSet(int initialCapacity, float loadFactor) {
  24. map = new HashMap<>(initialCapacity, loadFactor);
  25. }
  26. /**
  27. * 以指定的initialCapacity构造一个空的HashSet。
  28. * 实际底层以相应的参数及加载因子loadFactor为0.75构造一个空的HashMap。
  29. * @param initialCapacity 初始容量。
  30. */
  31. public HashSet(int initialCapacity) {
  32. map = new HashMap<>(initialCapacity);
  33. }
  34. /**
  35. * 以指定的initialCapacity和loadFactor构造一个新的空链接哈希集合。此构造函数为包访问权限,不对外公开,实际只是是对LinkedHashSet的支持。实际底层会以指定的参数构造一个空LinkedHashMap实例来实现。
  36. * @param initialCapacity 初始容量。
  37. * @param loadFactor 加载因子。
  38. * @param dummy 标记。
  39. */
  40. HashSet(int initialCapacity, float loadFactor, boolean dummy) {
  41. map = new LinkedHashMap<>(initialCapacity, loadFactor);
  42. }

3.HashSet的存储

  • add方法解析
   
 
  1. /**
  2. * 使用HashMap作为底层数据结构
  3. * 1.利用HashMap的key不重复原则实现非重
  4. * 2.由于HashMap的非有序导致HashSet的非有序
  5. * 3.HashMap的value使用一个final的static变量作为默认值
  6. * @Return 若put成功,返回true否则false (该方法在添加 key 不重复的键值对的时候,会返回 null)
  7. */
  8. public boolean add(E e) {
  9. return map.put(e, PRESENT)==null;
  10. }
  • clone方法解析
   
 
  1. /**
  2. * 返回此HashSet实例的浅表副本:并没有复制这些元素本身
  3. * @Return 底层实际调用HashMap的clone()方法,获取HashMap的浅表副本
  4. * 拓展:
  5. * 1.浅复制就是仅复制类中的值类型成员
  6. * 2.深复制就是复制类中的值类型成员和引用类型的成员
  7. */
  8. public Object clone() {
  9. try {
  10. HashSet<E> newSet = (HashSet<E>) super.clone();
  11. newSet.map = (HashMap<E, Object>) map.clone();
  12. return newSet;
  13. } catch (CloneNotSupportedException e) {
  14. throw new InternalError();
  15. }
  16. }
  • 迭代方法
   
 
  1. /**
  2. * 1.基于迭代器模式(Set接口定义Iterator<E> iterator()方法)
  3. * 2.迭代map的keySet集合
  4. */
  5. public Iterator<E> iterator() {
  6. return map.keySet().iterator();
  7. }
  • 归纳
    • 对于 HashSet 中保存的对象,请注意正确重写其 equalshashCode 方法,以保证放入的对象的唯一性
    • 有序可选用LinkedHashSetTreeSet
    • 线程安全可选用CopyOnWriteArraySetConcurrentSkipListSet

  • 内容目录


添加新批注
《集合番@HashSet一文通(1.7版)》
保存 取消 在作者公开此批注前,只有你和作者可见。
《集合番@HashSet一文通(1.7版)》 保存 取消
《集合番@HashSet一文通(1.7版)》
修改 保存 取消 删除

  • 私有
  • 公开
  • 删除

查看更早的 5 条回复
回复批注

×

通知

取消 确认

    原文作者:HashMap源码分析
    原文地址: https://juejin.im/entry/5971763e6fb9a06bba4740cd
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞