专栏首页在周末的专栏Java数据结构-------Set

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • RPC-Thrift(二)

        阻塞Server使用TServerSocket,它封装了ServerSocket实例,ServerSocket实例监听到客户端的请求会创建一个Socke...

    在周末
  • RPC-Thrift(四)

        同步客户端比较简单,以RPC-Thrift(一)中的的例子为基础进行研究源码,先看一下类图。

    在周末
  • Java并发编程--ThreadPoolExecutor

      合理利用线程池能够带来三个好处。第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。第二:提高响应速度。当任务到达时,任务可以不需要等...

    在周末
  • HashSet底层分析

    对于HashSet而言,它是基于HashMap实现的。HashSet底层采用HashMap来保存元素,因此HashSet底层其实比较简单。

    用户6182664
  • JDK1.8源码(八)——java.util.HashSet 类

      在上一篇博客,我们介绍了 Map 集合的一种典型实现  HashMap  ,在 JDK1.8 中,HashMap 是由 数组+链表+红黑树构成,相对于早期版...

    IT可乐
  • (Head First 设计模式)学习笔记(3) --装饰者模式(StarBuzz咖啡店实例)

    应用概述: StarBuzz咖啡店有很多饮料,每种饮料都可以根据客户需要加一些调料,比如深培咖啡可以加摩卡(或双倍摩卡),而且某些饮料可以分为大中小杯,根据容...

    菩提树下的杨过
  • JDBC 利用反射及 JDBC 元数据编写通用的查询方法(7)

    桑鱼
  • java设计模式(3)-建造者模式

    上一篇推文写了单例设计模式,这篇文章介绍和工厂模式类似的建造者模式,实际开发中,要根据情况使用不同的设计模式

    爱敲代码的猫
  • GenericFactoryMethod泛型工厂模式实现简单IOC功能

    泛型工厂理论上不算Gof23中设计模式之一,但是也算是一种非常好的设计模式,个人认为,废话不多说,先写个简单的抽象工厂,在写一个泛型工厂的例子来比较抽象和泛型的...

    郑小超.
  • 慕课网高并发实战(六)- 线程安全策略

    ThreadLocal 实例保存登录用户信息 (具体的业务场景,和拦截器的使用就不赘述了,大家可以购买课程详细学习)

    Meet相识

扫码关注云+社区

领取腾讯云代金券