JAVA集合详细讲解和线程安全

本文详细介绍了Java中的集合框架,包括单列集合(如List和Set,尤其是ArrayList、LinkedList和HashSet/TrieSet的区别),双列集合(特别是HashMap和TreeMap的实现原理),以及线程安全的考虑,如Vector和ConcurrentHashMap。同时讨论了线程安全概念和悲观锁、乐观锁的使用。
摘要由CSDN通过智能技术生成

java中的集合总共分为两大类,单列集合collection和双列集合map,常用的,单列集合list、set。

单列集合:

list集合:元素可重复,有序。list集合的子类有ArrayList和LinkedList,ArrayList底层是数组,查询快,增删慢,数组中的空间都是连续的,查询快是因为数组有索引,可以通过索引来直接访问,增加和删除速度快是因为添加或者删除都需要移动元素,就比如数据(1,2,3,5)我们想删除2,那么3、5元素都需要向前移动,LinkedList底层是链表,查询慢,增删快,链表是不连续的空间,查询慢是因为即使我们知道元素在哪也只能遍历链表才能找到,通过指针指向,增删快我们可以直接改变头尾指针指向的结点即可,不需要移动元素,链表里有两块区域(数据区和下一个结点的地址),也就是说不是按照顺序存放,当添加一个元素时,直接改变指针域的地址即可

set集合:元素不可重复,无序。set的子类有HashSet和TreeSet,HashSet其实就是一个HashMap,当我们new HashSet对象时,也就相当于new了一个HashMap,存放数据时,将我们存放的元素当作键来放在map中,TreeSet底层是TreeMap,底层是是红黑树

双列集合:

map子类有HashMap和TreeMap,HashMap基于hash表实现的,在jdk1.8之后底层是通过数组+链表+红黑树来实现的,在创建HashMap之前会先创建一个数组,默认长度为16,map集合是根据键值对来存储的,根据key的hash值%数组长度,得到的数据一定在长度之内,那么根据算出来的数据存在对应的位置,如果该位置为空则存入,否则去遍历链表看key是否一致,一致则视为同一个数据,覆盖,不同则将生成一个链表挂在数组的下面,但是链表的查询效率是比较低的,如果每次存都要通过链表遍历的话效率慢,自此引入了红黑树的概念,就是当链表的长度超过8位之后,就会自动将链表转换成红黑树,左边存放的是比根节点小的数字,右边存放比根节点打的数字,如果每次存放的数据都比根节点小或都比根节点大的话,都挂在左边或右边,这样又形成了链表的结构,所以引入了平衡二叉树,那么如果我们要存放的数据很多的话,也引入了扩容机制,当前长度*加载因子=……

就比如默认长度16*加载因子默认0.75=12,那么当存放第12个数据时,就会触发扩容机制,扩容为原来长度的两倍,也就是32个,是重新生成了一个数组而不是在之前的16之后加了,并把原来的数据拷贝过去,

TreeMap:基于红黑树实现的,默认是根据键来进行升序排序的,底层由红黑树构成,键不能重复,允许null值和null键

以上所有集合线程都是不安全的,要想满足线程安全可以使用Vector和ConCurrentHashMap

那么什么是线程安全呢,所谓线程安全就是内存安全,如果有多个线程共享一块区域那么一定会存在安全问题,我们可以使用加锁的方式来处理线程不安全问题,也就是说AB共享同一个时,当A在未完成自己的操作时B不能抢占资源,要等A线程处理完自己的会进行锁的释放,这时B才能来修改数据。1、悲观锁:该线程总认为会有别的线程回来抢占资源,先进行加锁  2、乐观锁:见名知意,认为不会有线程抢占资源,等去操作时先判断是否被更改,如果被更改则进行加锁。

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘猫_A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值