HashSet和TreeSet,及HashMap与其他相关映射的比较

HashSet:元素不可重复,无序,底层是通过在内部建一个HashMap的实例对象,几乎全部调用HashMap的方法来实现。

TreeSet:元素不可重复,有序,底层是通过在内部建一个TreeMap的实例对象,几乎全部调用TreeMap的方法来实现。

所以下面重点分析HashMap和TreeMap来解释:

HashMap:初始容量为16,加载因子0.75,可以存null,异步式线程不安全,键不可重复,值可重复,键值对重复就覆盖。

本质上是基于可变数组和链表实现的(jdk1.8之后如果链表长度超过8,链表就转变为红黑树,以后长度小于6时再转变为链表),初始容量为16,加载因子为0.75即长度为16的数组,每当超过0.75的总容量时扩容,每个元素称为桶,桶内部存方了一个链表用来存储键值对。

底层源码中键值对Entry的hash值,是根据键K和值Value的hash值通过^(抑或位运算)求得,所以当Value值为空时Entry的hash值就是K的hash值,可以被HashSet(可以认为是没有Value的键值对映射)直接借用。Entry的hash值确定存放桶的位置,如果桶内有元素,就通过equals方法分别比较,如果相同就覆盖原有元素,如果不同则放入链表的第一个位置。一旦扩容所有键值对元素都必须重新hash再存入新的HashMap中,频繁扩容开销比较大,应当尽量避免,在构造函数中指定好合适的初始容量。

综合以上叙述可以看到,HashMap结合了可变数组及链表的优势,查询定位及增删效率都比较高。

TreeMap:是通过红黑树实现的,所以不存在初始容量及加载因子的概念,键值对元素通过实现Comparable接口实现compareTo方法比较来确定顺序,当元素没有实现此接口时,需要程序员指定外比较器Comparator重写compare方法来比较得出顺序,红黑树是一个自平衡的二叉树(最末尾子节点层数差不超过1),每当有元素增删时,通过恢复红黑树第四条和第五条原则实现调整树结构(此处较为复杂建议查看https://blog.csdn.net/mbmispig/article/details/78750405,写的是我查阅资料里面最为全面的)

HashMap扩展:Hashtable、ConcurrentHashMap、LinkedHashMap、WeakHashMap

Hashtable:线程安全,初始容量13,加载因子0.75,所有方法都被Syncharonized关键字锁住,每当操作数据时,将整个表锁住以此保证数据安全。

ConcurrentHashMap:初始条件同Hashtable,异步式线程安全,操作数据时,通过锁住当前数据所在的桶,其他桶仍然可以操作,以此保证数据安全,较为推荐。

LinkedHashMap:在HashMap基础上增加一个链表记录元素增删查询记录,以此来记录元素的顺序,在记录重要配置的操作日志时可以用到。

WeakHashMap:当使用HashMap处理海量数据时,频繁的扩容消耗系统性能,无用内存始终占用导致内存大量浪费,由于HashMap是强引用,内部元素不被引用也不会被清除,而WeakHashMap中的元素是若引用,每次gc收集垃圾时标记未被引用的元素,维护在一个待处理队列表中,当我们再次操作WeakHashMap时,就会比对待处理队列当中的元素,如果没有处理,那么待处理队列中的元素都将被清除。数据处理效率极高!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值