java常用数据结构

List:ArrayList 和 LinkedList

     1、ArrayList 和 LinkedList都是非线程安全
     2、ArrayList 可以直接根据下表定位元素,查找速度快,但是修改元素慢;LinkedList 查找元素必须从第一个开始逐个查找,查找速度慢,但是修改元素快
     3、当多个线程访问list时,因为每两个相邻节点之间存在前后关系(指针或内存地址),所以多个线程同时对list添加数据时会报错

Set:HashSet、LinkedHashSet、TreeSet

     1、HashSet:存放的元素是无序的,可以存null
     2、TreeSet: 存放的数据是有序的(根据存放的数据排序,而不是存放的先后顺序,同时也提供了排序规则的构造函数),不能存null
     3、LinkedHashSet: 有序,基于链表实现
     4、HashSet、TreeSet、LinkedHashSet都是非线程安全的

Map:HashMap、TreeMap、Hashtable、ConcurrentHashMap

    1、HashMap 非线程安全,数据是无序的,可存储空的键或值,查找的事件复杂度是O(1),
    2、TreeMap 非线程安全,基于红黑树实现,根据键的自然顺序或Comparator 来排序,查找的事件复杂度是O(logn)
    3、Hashtable 通过在方法上加 synchronized实现了线程安全,性能差

         也可以通过 Collections.synchronizedMap(hashMap) 获得一个线程安全的类,也是通过在方法上加 synchronized实现线程安全

     4、ConcurrentHashMap:是线程安全的,通过put方法看一下ConcurrentHashMap的原理

           从下面的代码可以看到ConcurrentHashMap是通过cas、synchronized在方法里面加锁,锁的粒度比Hashtable要小,所以效率更高;

           在jdk1.7中使用了Segment 来优化来提高效率,一个ConcurrentHashMap中默认有16个Segment ,每个Segment都是线程安全的,而且Segment负责一段hash值,这样可以最多16个线程同时对map操作,但在jdk1.8中不再使用Segment,虽然代码中仍然有Segment知识为了兼容以前的版本;

final V putVal(K key, V value, boolean onlyIfAbsent) {
        if (key == null || value == null) throw new NullPointerException();
        //获取键的hash值
        int hash = spread(key.hashCode());
        int binCount = 0;
        for (Node<K,V>[] tab = table;;) {
            Node<K,V> f; int n, i, fh;
            //1、判断 table 如果为空,就初始化,tabel是一个node数组,默认大小为16
            if (tab == null || (n = tab.length) == 0)
                tab = initTable();
            //2、判断i位置是否为空,如果是就将 key和value封装成node放在i位置,通过cas(unsafe接口)实现    
            else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
                if (casTabAt(tab, i, null,
                             new Node<K,V>(hash, key, value, null)))
                    break;                   // no lock when adding to empty bin
            }
            //3、如果i位置不为空,并且i位置的节点的hash为-1,则说明table正在扩容中
            else if ((fh = f.hash) == MOVED)
                tab = helpTransfer(tab, f);
            //4、如果i位置不为空,并且节点的key的hash不为-1,则更新节点
            else {
                V oldVal = null;
                synchronized (f) {
                    if (tabAt(tab, i) == f) {
                         4.1这一段是插入链表的逻辑
                        if (fh >= 0) {
                            binCount = 1;
                            for (Node<K,V> e = f;; ++binCount) {
                                K ek;
                                if (e.hash == hash &&
                                    ((ek = e.key) == key ||
                                     (ek != null && key.equals(ek)))) {
                                    oldVal = e.val;
                                    if (!onlyIfAbsent)
                                        e.val = value;
                                    break;
                                }
                                Node<K,V> pred = e;
                                if ((e = e.next) == null) {
                                    pred.next = new Node<K,V>(hash, key,
                                                              value, null);
                                    break;
                                }
                            }
                        }
                         4.2这一段时插入红黑树的逻辑
                        else if (f instanceof TreeBin) {
                            Node<K,V> p;
                            binCount = 2;
                            if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
                                                           value)) != null) {
                                oldVal = p.val;
                                if (!onlyIfAbsent)
                                    p.val = value;
                            }
                        }
                    }
                }
                if (binCount != 0) {
                    //  当链表中的元素个数超过八个时自动转为红黑树
                    if (binCount >= TREEIFY_THRESHOLD)
                        treeifyBin(tab, i);
                    if (oldVal != null)
                        return oldVal;
                    break;
                }
            }
        }
        addCount(1L, binCount);
        return null;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/316618.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM内存模型理解

1、首先理解下什么是 jvm 内存模型&#xff1f; jvm内存模型定义了Java虚拟机运行时如何组织和管理内存&#xff0c;规定了各个内存区域的作用、结构和交互方式&#xff0c;以及线程间的内存可见性、内存操作的原子性等行为&#xff0c;以支持Java程序的执行&#xff0c;即一种…

【Pytorch】学习记录分享11——PyTorch GAN对抗生成网络

PyTorch GAN对抗生成网络 0. 工程实现1. GAN对抗生成网络结构2. GAN 构造损失函数&#xff08;LOSS&#xff09;3. GAN对抗生成网络LOSS损失函数说明 0. 工程实现 1. GAN对抗生成网络结构 2. GAN 构造损失函数&#xff08;LOSS&#xff09; LOSS公式与含义&#xff1a; LOSS…

【qt】解决qt里编辑qss后失效问题(qt编码问题)

1、先创建qss文本stylesheet.qss 以按钮为例 QPushButton {background-color:rgb(240,255,255);color: rgb(0, 0, 2);border-style: outset;border-color: beige;border-radius: 10px; }/* hover按钮悬浮&#xff0c;鼠标悬浮在按钮上的状态&#xff0c;按钮颜色 */QPushButto…

【Vue2+3入门到实战】(19)Vuex状态管理器通过辅助函数 - mapState获取 state中的数据代码实现 详细讲解

目录 一、通过辅助函数 - mapState获取 state中的数据1.第一步&#xff1a;导入mapState (mapState是vuex中的一个函数)2.第二步&#xff1a;采用数组形式引入state属性3.第三步&#xff1a;利用**展开运算符**将导出的状态映射给计算属性 二、开启严格模式及Vuex的单项数据流1…

初识Linux下进程

&#x1f30e;初识进程 初识进程 简单认识一下进程 如何管理进程 进程属性信息 内核运行队列 查看进程 通过系统调用获取进程标识符       父子进程       查看运行中的进程 总结 前言&#xff1a; 我们在电脑上点开的一个个应用&#xff0c;其实就是一个个进程&am…

用 MATLAB 产生单位抽样序列、单位阶跃序列、矩形序列、正弦序列和复指数序列

%% 单位抽样&#xff08;脉冲&#xff09;序列&#xff08;冲激函数&#xff09; % 参数设置 n -10:10; % 定义时间范围 delta (n 0); % 生成单位抽样序列% 绘图 figure; stem(n, delta); title(单位抽样序列); xlabel(n); ylabel(delta[n]);%% 单位阶跃序列 % 参数设置 n …

STM32F407-14.3.10-表73具有有断路功能的互补通道OCx和OCxN的输出控制位-01x00

如上表所示&#xff0c;MOE0&#xff0c;OSSI1&#xff0c;CCxE0&#xff0c;CCxNE0时&#xff0c;OCx与OCxN的输出状态取决于GPIO端口上下拉状态。 ---------------------------------------------------------------------------------------------------------------------…

亚马逊、速卖通新店怎样提高权重?测评养号助力产品脱颖而出

对于亚马逊的新店铺来说&#xff0c;提高权重是十分关键的。通过提高权重&#xff0c;可以增加店铺的曝光度和可信度&#xff0c;吸引更多的买家。那么&#xff0c;亚马逊新店怎么样提高权重呢? 一、亚马逊新店怎么样提高权重? 优质商品与服务&#xff1a;首先&#xff0c;…

以 RoCE+软件定义存储同时实现信创转型与架构升级

目前&#xff0c;不少企业数据中心使用 FC 交换机和集中式 SAN 存储&#xff08;以下简称“FC-SAN 架构”&#xff09;&#xff0c;支持核心业务系统、数据库、AI/ML 等高性能业务场景。而在开展 IT 基础架构信创转型时&#xff0c;很多用户受限于国外交换机&#xff1a;FC 交换…

地平面--高速布线

https://baijiahao.baidu.com/s?id1764139038516816855&wfrspider&forpc 概念 回顾传输线&#xff0c;由任意两条有一定长度的导线组成&#xff0c;一条为信号路径&#xff0c;一条为返回路径。基本电路理论告诉我们&#xff0c;信号是由电流传播的&#xff0c;明确的…

swing快速入门(三十六)分割面板

&#x1f941;注释很详细&#xff0c;直接上代码 上一篇 &#x1f512;新增内容&#xff1a; &#x1f5dd;️1.列表选中事件监听器 &#x1f5dd;️2. 分割面板的垂直和水平方式创建 &#x1f5dd;️3.“一触即展”特性开关 &#x1f5dd;️4.分割面板大小自适应 &#…

关于“Python”的核心知识点整理大全58

目录 19.2.3 注销 1. 注销URL urls.py 2. 视图函数logout_view() views.py 3. 链接到注销视图 base.html 19.2.4 注册页面 1. 注册页面的URL模式 urls.py 2. 视图函数register() views.py 3. 注册模板 register.html 4. 链接到注册页面 base.html 注意 19.3 …