java集合

什么是集合

        集合是存放数据的容器,准确的说是存放数据对象引用的容器。

        集合都是存放对象的引用,不是存放对象本身

        集合类主要有三种:List、Map、Set

List(列表)

ArrayList(数组列表)

        ArrayList继承自 AbstractList 类,底层通过数组实现容量动态化,对数据进行插入、删除时都需要对数组进行拷贝并且重新排序,查询快、增删慢、线程不安全、效率高。

        想要使ArrayList线程安全有三种方式

                1.自己写个包装类,根据业务一般是add/update/remove加锁

                2.Collections.synchronizedList(new ArrayList<>()); 使用synchronized加锁

                3.CopyOnWriteArrayList<>()  使用ReentrantLock加锁

        ArrayList的扩容机制

                JDK1.7之前默认大小是10,JDK1.7之后默认大小是0

                未指定集合容量默认为10,若已指定集合大小集合大小为指定容量

                当集合第一次添加元素是,扩容容量为10

                ArrayList的扩容容量为1.5倍

LinkedList(双向列表)

        LinkedList继承 AbstractSequentialList 类,底层通过双向链表实现,因为LinkedList同时实现了List接口和Qeque(double ended queue(双端队列))对口,所以他既可以看成一个循序容器,也可以当成一个队列,所以可以当成或者队列来使用。

        查询慢、增删快、线程不安全、效率高。

Vector

        Vector继承于 AbstractList 类,底层通过数组实现,查询快、增删慢、线程安全、效率低,Vector的扩容容量为两倍。

Stack

        通过继承Vector类,Stack类可以很容易的实现他本身的功能。因为大部分的功能在Vector里面已经提供支持了。

ArrayQueue(数组队列)

        ArrayQueue继承于双端队列,ArrayQueue是没有边界的,在栈的使用中ArrayQueue比Stack,LinkedList更快,ArrayQueue的线程是不安全的。

Vector、ArrayList、LinkedList的区别

        ArrayList扩容之后容量增加1.5倍,Vector默认情况下扩容之后容量增加两倍,Vector可以设置容量增量而ArrayList不可以。

Map

HashMap

        HashMap继承于AbstractMap,底层是哈希表是无序集合,查询速度快,可以存储null,key不可重复,重复则会被覆盖,HashMap线程不安全。

        HashMap的内部数据结构在各个版本的实现中略有不同,在JDK1.7中数据结构是单链表+数组,在JDK1.8及之后数据结构是单链表+数组+红黑树

        HashMap的默认长度为16,负载因子为0.75,负载因子为0.75的意思是当元素沾满map的75%时,进行扩容,扩容的长度为两倍,扩容之后重新排序。

        适用于较少的线程的需求,如果线程较大可以用 ConcurrentHashMap 替代。

        当数据需要映射关系是应该优先使用Map。
 

LinkedHashMap

        LinkedHashMap继承于HashMap,他的多种操作都是建立在HashMap的操作基础上的,LinkedHashMap维护了一个Entry的双向链表,保证了Entry插入的顺序。

TreeMap

        TreeMap继承于AbstractMap,底层为红黑树,默认根据Key的自然顺序排序或者根据创建Map时的Comparator进行排序。

        线程不安全、key不能存null。

        进行增删查时时间复杂度为O(log2 n),而HashMap的时间为O(1)

Set

HashSet

        HashSet底层通过HashMap实现为无序Set,HashMap是通过链表+数组+红黑树实现的,增删查找的时间复杂度为O(1),线程不安全,元素可为null,

        在使用HashSet时,所有的值都是存储在一个HashMap的Key上的。

        HashSet不能存入相同元素是因为,重写了HashCode()和equals(),当先HashSet添加元素的时候,首先计算元素的HashCode值,然后通过扰动计算和按位与的方式计算出这个元素的存储位置,如果这个位置为空,就将元素添加进去,如果不为空,则用equals()方法来比较元素是否相等,先等就不添加,否则找一个空位添加。

LinkedHashSet

        LinkedHashSet时HashSet的子类,底层通过LinkedHashMap实现,维护了一个数组+双向链表,和HashSet不同的是,双向链表可以维护元素的次序,因此使得LinkedHashSet有序。

SortedSet

        SortedSet是一个接口,他只有TreeSet这一个实现可用,它包含的元素是在内部排序的。

TreeSet

        TreeSet底层通过TreeMap实现,TreeMap是通过红黑树实现的,按元素的自然顺序排序,线程不安全,元素不可为null,时间复杂度为O(logN)

        在使用TreeSet时,所有的值都是在一个TreeMap的Key上的。

        TreeSet是通过compare To()来判断重复的。

Queue

Deque

        Deque是双端队列的缩写,是queue的一个子类,是一个支持两端元素插入和删除操作的线性集合,可以把它当做队列来使用。

        与List接口不同,该接口不支持对元素的索引访问。

ArrayDeque

        ArrayDeque是Deque的一个子类,线程不安全,可以当成栈或队列来使用,效率高于Stack和LinkedList,ArrayDeque不支持null值。

        Deque的元素存储在一个可变数组里,Deque的容量大小是数组的长度,数组的长度是2的幂,默认长度为16,且数组不能被填满,在被填满是立即改变大小,从而避免头尾绕城相等。

PriorityQueue

        队列中除了Stack和queue还有一种特殊的队列PriorityQueue(优先队列),优先队列的作用是能让内部元素进行排序。

        PriorityQueue是由二叉小顶堆实现,可以用一颗完全二叉树来表示,不可插入null元素,大小是无界的。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值