JAVA 常见集合总结

Java常用集合
一、数据结构
1、数组
时间负载度为o(1),空间复杂度为哦o(n) ,所以查询比较快,删除,插入、更新比较慢

2、链表
时间复杂度为o(n)因为要一条一条去比较,空间复杂度为o(1),所以查询比较慢,删除,插入、更新比较快
3、Hash表
所有复杂度都为o(1),唯一不好有hash冲突,但它不是有序的,无法进行范围查询
4、二叉树
对一棵相对平衡的有序二叉树,对其进行插入,查找,删除等操作,平均复杂度均为O(logn)
5、红黑树(平衡树)
平衡树虽然也很好,但它每一次的插入和删除都可能导致全局调整,耗时多时间复杂度O(logn)
6、跳跃表
它是在链表的基础上改进而来的,虽然跳跃表的具体实现有很多种,但它的主要思想都是在有序的链表上(原始链表),随机提取一些关键结点到上一层形成一个新的有序链表作为索引链表,当然为了提高查找效率,索引链表往往不会只是一层,而是在索引链表中再提取一些关键结点到上一层形成更高一层的有序索引链表,不断的提取以此形成多层链表(Redis底层使用的跳表最多允许32层)

二、集合
1、MAP
(1)HashTable集合(无序,线程安全)
数据结构采用hash表,线程安全,底层使用synchronized加锁保持同步,不允许有空键和空值,空值在一进入put方法就抛出空指针异常,空键在计算hashcode的时候抛出空指针异常,里面重要的方法基本都加了锁,像put、get、remove、contains、keys、isEmpty、size等,底层通过Entry数组进行存储,初始容量是即数组长度11、负载因子大小0.75、首次扩容临界值阀值(110.75)8,当达到临界值时以原来数组长度的2倍+1进行扩容
(2)HashMap集合(无序,线程不安全)
数据结构采用数组加链表进行存储,线程不安全,允许有1个空键和多个空值,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。jdk1.8以后引入了红黑树,即当链表超过节点数大于等于8时,链表就转换为红黑树,底层通过Entry数组进行存储(每个Entry中存储的是hash、key、value、next(指向下一个元素)),当遇到hash冲突时采用链表存储,jdk1.7采用头插法,这种方式在高并发时容易产生死锁,所以jdk1.8以后使用尾插法,初始容量是即数组长度16、负载因子大小0.75、首次扩容临界值阀值(16
0.75)12,当达到临界值时以原来数组长度的2倍进行扩容,HashMap数据索引值计算通过对key进行key.hashCode(),然后再进行二次hash得到,二次hash为了使存储更散列,不容易发送hash冲突。
(3)ConcurrentHashMap 集合(无序,线程安全)
数据结构采用数组加链表进行存储dk1.8以后引入了红黑树,线程安全,jdk1.7采用分段锁解决线程安全,分段锁即底层把每个数组逻辑上进行分组,对每个组进行加synchronized锁这也效率比hashTable高了很多。Jdk1.8以后引入了CAS,效率有提升了n倍

(4)LinkedHashMap 集合(有序,线程不安全)
LinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构。该结构由数组和链表+红黑树 在此基础上LinkedHashMap 增加了一条双向链表,保持遍历顺序和插入顺序一致的问题。允许使用null值和null键, 线程是不安全的,虽然底层使用了双线链表,但是增删相快了。因为他底层的Entity 保留了hashMap node 的next 属性。保证有序重其实新定义了数组中保存的元素Entry(继承于HashMap.node),该Entry除了保存当前对象的引用外,还保存了其上一个元素before和下一个元素after的引用,从而在哈希表的基础上又构成了双向链接列表。仍然保留next属性,所以既可像HashMap一样快速查找
(5)TreeMap集合(有序,线程不安全)
1、保证了有序性。默认的排序是根据key值进行升序排序,也可以重写comparator方法来根据value进行排序具体取决于使用的构造方法。不允许有null值null键。TreeMap是线程不安全的。
2.TreeMap基于红黑树(Red-Black tree)实现。TreeMap的基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n) 。

(6)ConcurrentSkipListMap集合(有序,线程安全)
数据结构在链表的基础上进行了改进,时间复杂度为o(logn),线程安全,数据结构为跳跃表,其实就是对链表进行不断的向上抽取,形成一层,实现比平衡数等简单,且时间复杂度和平衡树基本一样

2、SET
(1)hashSet集合(无序,线程不安全)
hashset是基于hashmap实现的,默认构造函数是构建一个初始容量为16,负载因子为0.75的hashmap,封装了一个hashmap 对象来存储所有的集合元素,所有放在 hashset中的集合元素实际上由 hashmap的key来保存,而 hashset中的 hashmap的 value则存储了一个PRESENT的静态object对象
(2)TreeSet 集合(有序(不保证插入顺序,按自然顺序),线程不安全)
Treeset是基于treemap实现的,TreeSet 底层实际使用的存储容器就是 TreeMap,属于sortedSet接口实现
(3)ConcurrentSkipListSet集合(有序,线程安全)
ConcurrentSkipListSet是通过ConcurrentSkipListMap实现的

3、List
(1)ArrayList集合(无序,线程不安全)
ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长, ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。ArrayList提供了根据下标或者指定对象两种方式的删除功能。romove(int index),首先是检查范围,修改modCount,保留将要被移除的元素,数组进行扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的0.5倍。这种操作的代价是很高的,因此在实际使用时,我们应该尽量避免数组容量的扩张。当我们可预知要保存的元素的多少时,要在构造ArrayList实例时,就指定其容量。ArrayList基于数组实现,可以通过下标索引直接查找到指定位置的元素,因此查找效率高,但每次插入或删除元素,就要大量地移动元素,插入删除元素的效率低

(2)LinkedList集合(有序,线程不安全)
LinkedList的底层是通过链表来实现的。链表是由多个节点构成,每个节点都包含三个部分,头部指向上一个节点,中部指向该节点,尾部指向下一个节点双向链表。缺点:添加慢,因为需要遍历找到到最后一个指向为null的节点。优点:插入和删除快 因为可以直接改变下一个节点的指向

(3)Vector集合(有序,线程安全)
Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢,发现当数组的大小不够的时候,需要重新建立数组,然后将元素拷贝到新的数组内,ArrayList和Vector的扩展数组的大小不同每次数组容量的增长大约是其原容量的1倍,其线程安全的实现方式是对所有操作都加上了synchronized关键字,这种方式严重影响效率,因此,不再推荐使用Vector了
(4)Collections.synchronizedList 集合(无序有序根据传入集合确定 写操作性能高 线程安全)
(4)CopyOnWriteArrayList 集合(无序 读操作性能高 线程安全)
三、集合图
不是严格按照继承关系画的
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值