• Java数据结构-------Set


    三种常用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;

     1 public class HashSet<E>
     2     extends AbstractSet<E>
     3     implements Set<E>, Cloneable, java.io.Serializable
     4 {
     5     static final long serialVersionUID = -5024744406713321676L;
     6 
     7     private transient HashMap<E,Object> map;
     8     //定义一个"虚拟"的static final Object对象作为HashMap的value
     9     // Dummy value to associate with an Object in the backing Map
    10     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。

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

         添加

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

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

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

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

        清空与删除

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

        其他

     1     //返回此set中的元素的数量
     2     public int size() {
     3         return map.size();
     4     }
     5 
     6     //如果此set不包含任何元素,则返回 true
     7     public boolean isEmpty() {
     8         return map.isEmpty();
     9     }
    10 
    11     //返回此 HashSet实例的浅表副本
    12     @SuppressWarnings("unchecked")
    13     public Object clone() {
    14         try {
    15             HashSet<E> newSet = (HashSet<E>) super.clone();
    16             newSet.map = (HashMap<E, Object>) map.clone();
    17             return newSet;
    18         } catch (CloneNotSupportedException e) {
    19             throw new InternalError(e);
    20         }
    21     }

        迭代器

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

    参考资料

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

  • 相关阅读:
    工作实战之项目常用技术
    Thymeleaf的错误解决方式
    实用小demo
    idea常用的几个插件
    idea2019+Plugins中搜索不到任何插件解决办法
    git的初体验
    springboot2.+的整合log4j2错误解决浅谈
    MobaXterm百度网盘下载
    阿里云RDS云数据库连接步骤
    读源码学编程之——死循环妙用
  • 原文地址:https://www.cnblogs.com/zaizhoumo/p/7600084.html
Copyright © 2020-2023  润新知