HashSet、LinkedHashSet、TreeSet

简介:

关于HashSet、LinkedHashSet、TreeSet

Set接口的实现类,最大特点是不允许出现重复元素;

HashSet:基于HashMap实现,一个性能相对较好的Set;

LinkedHashSet:基于LinkedHashMap实现,一个保存了插入顺序的Set;

TreeSet;基于TreeSet实现,一个实现了排序的Set;

类图关系

源码分析

Set接口的实现类相对来说都比较简单,如果熟悉HashMap、LinkedHashMap、TreeMap源码的话,HashSet、LinkedHashSet、TreeSet的代码会很好理解,因为基本上都是调用对应Map的方法来实现的;

HashSet部分源码

复制代码
package java.util;
public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
    static final long serialVersionUID = -5024744406713321676L;

    //存储元素的HashMap
    private transient HashMap<E,Object> map;

    // 一个冗余的空对象,用于在Map中存放key对应的value,Map中所有的键值对的value都是同一个空Object的引用
    private static final Object PRESENT = new Object();

    /**
     * 构造方法,直接生成一个对应的HashMap
     */
    public HashSet() {
        map = new HashMap<>();
    }

    //省略一部分代码.....
    
    
    //返回HashMap的key迭代器,HashSet中的元素实际上就是HashMap中的key元素
    public Iterator<E> iterator() {
        return map.keySet().iterator();
    }

    //调用HashMap的put方法,将e-PRESENT键值对对象put到map中
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

    //省略一部分代码.....
}
复制代码

LinkedHashMap源码,如下,代码很少,主要是构造方法,

根据传入的参数,调用父类HashSet的HashSet(int initialCapacity, float loadFactor, boolean dummy)方法,生成一个LinkedHashMap对象存储集合元素:

复制代码
package java.util;
public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {
        
    private static final long serialVersionUID = -2851667679971038690L;

    public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }
    
    public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }

    public LinkedHashSet() {
        super(16, .75f, true);
    }

    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }
}
复制代码

HashSet中生成LinkedHashMap的构造方法HashSet(int initialCapacity, float loadFactor, boolean dummy)

    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

TreeSet部分源码

有一个NavigableMap类型的Map和一个空对象,NavigableMap会在构造方法里被赋成一个TreeMap对象,PRESENT是所有键值对中value对象的同一个引用;

复制代码
public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{
    /**
     * TreeMap对象
     */
    private transient NavigableMap<E,Object> m;

    // 空对象,所有Map键值对中value对象的同一个引用
    private static final Object PRESENT = new Object();
复制代码

构造方法,可见TreeSet是基于TreeMap实现的:

复制代码
    TreeSet(NavigableMap<E,Object> m) {
        this.m = m;
    }

    public TreeSet() {
        this(new TreeMap<E,Object>());
    }
复制代码

再看其它TreeSet中方法的源码,基本都是通过调用TreeMap的方法实现;

复制代码
 //省略部分代码。。。
 public NavigableSet<E> descendingSet() {
        return new TreeSet<>(m.descendingMap());
    }
    public int size() {
        return m.size();
    }

    public boolean isEmpty() {
        return m.isEmpty();
    }
//省略部分代码。。。
复制代码

补充一句

学好Set集合的关键是把Map学好。

 本文转自风一样的码农博客园博客,原文链接:http://www.cnblogs.com/chenpi/p/5297472.html,如需转载请自行联系原作者

相关文章
|
12月前
|
存储 边缘计算 安全
深入解析边缘计算:架构、优势与挑战
深入解析边缘计算:架构、优势与挑战
1859 209
|
定位技术 C# 图形学
从零开始的unity3d入门教程(二)----基本功能讲解
这是一篇Unity3D入门教程,详细介绍了Unity界面操作、游戏物体创建修改、场景搭建、玩家控制、音效添加以及游戏测试和导出的全过程。
从零开始的unity3d入门教程(二)----基本功能讲解
|
数据采集 JSON 数据格式
Python大麦网演唱会数据爬取
Python大麦网演唱会数据爬取
935 0
|
自然语言处理
大模型在应用中面临的局限性
【7月更文挑战第25天】大模型在应用中面临的局限性
2101 3
|
算法 C++
蓝桥杯第十三讲--树状数组与线段树【例题】(一)
蓝桥杯第十三讲--树状数组与线段树【例题】
331 0
蓝桥杯第十三讲--树状数组与线段树【例题】(一)
|
C语言
【C 语言】结构体 ( 结构体类型定义 | 结构体类型别名 | 声明结构体变量的三种方法 | 栈内存中声明结构体变量 | 定义隐式结构体时声明变量 | 定义普通结构体时声明变量 )
【C 语言】结构体 ( 结构体类型定义 | 结构体类型别名 | 声明结构体变量的三种方法 | 栈内存中声明结构体变量 | 定义隐式结构体时声明变量 | 定义普通结构体时声明变量 )
730 0
|
数据可视化 定位技术 数据格式
快速制作地图图表—ChartCube 地图制图工具尝鲜体验
# 快速制作地图图表—ChartCube 地图制图工具尝鲜体验 ![2020-03-03 12-39-26.2020-03-03 13_17_22.gif](https://gw.alipayobjects.com/mdn/rms_855bab/afts/img/A*okWHQaEeEYcAAAAAAAAAAABkARQnAQ) ChartCube 图表魔方是:AntV 在线图表制作工
3977 0
如何将钉钉和企业邮箱结合起来使用
最近在研究一个目前常见的企业办公模式,企业邮箱和钉钉的结合。 企业邮箱已经成为企业在现今互联网时代中不可缺少的通讯工具之一,企业邮箱的地址格式一般为“员工姓名@公司域名”,相对于个人邮箱,企业邮箱能为企业带来更多价值。
8552 0
|
机器学习/深度学习 消息中间件 存储
监控指标10K+!携程实时智能检测平台实践
本文将介绍携程实时智能异常检测平台——Prophet。到目前为止,Prophet 基本覆盖了携程所有业务线,监控指标的数量达到 10K+,覆盖了携程所有订单、支付等重要的业务指标。Prophet 将时间序列的数据作为数据输入,以监控平台作为接入对象,以智能告警实现异常的告警功能,并基于 Flink 实时计算引擎来实现异常的实时预警,提供一站式异常检测解决方案。
监控指标10K+!携程实时智能检测平台实践
|
SQL 分布式计算 运维
DataWorks
DataWorks
1975 0