简单说说Java集合

java集合

对于使用:

  • 如果是集合类型,有List和Set供我们选择

    • List 插入有序,可重复

      • ArrayList 底层数据结构是数组 线程不安全

        添加元素如何实现? 先去检查数组的容量是否够,够了就直接添加,不够了先扩容为当前容量的1.5倍,第一次扩容后还不够的话就直接将容量扩充为一个minCapacity(就是size+1)

        增删的时候底层实现是依靠数组的复制,这个数组复制的方法由c/c++实现

      • LinkedList 底层数据结构是链表 线程不安全 还实现了Deque接口 操作他可以像操作队列和栈一样

        他这个数据结构是双向链表(方便往前遍历),双向链表每个节点都存着pre和next,单链表只是每个节点存个next

        关于查找 底层实现是先判断下标小于长度的一半就从头遍历,否则就从尾遍历

      • Vector 底层数据结构是数组 线程安全 现在已经很少用 被ArrayList替代

        就是每个方法上加了synchronize同步,扩容的话是扩容增加1倍,ArrayList是增加0.5倍

        被ArrayList替代的原因

        • 所有方法都是同步, 有性能损失
        • 扩容的话直接扩容增加一倍,比ArrayList更消耗内存
      • 总的来说,查询多用ArrayList,增删多用LinkedList

        对于数组来说如果往中间插入个值得话元素都得移动,是很可怕的

    • Set 插入无序 ,不可重复

      • HashSet 底层数据结构是哈希表,什么是哈希表呢?是一个数组,但是元素是链表

        其实HashSet底层就是一个HashMap实例,HashSet实际就是对HashMap封装了一下,并且底层使用的HashMap的Value都是一个Object对象

      • TreeSet 底层数据结构是红黑树(一个自平衡的二叉树) 还可以保证元素的排序方式

        实现了NavigableSet接口,可以实现排序,底层实际就是个TreeMap实例,非同步也就是线程不安全

      • LinkedHashSet 底层数据结构由哈希表和链表组成

        迭代有序,允许为空,非同步,底层HashMap加一个双向链表(其实就是LinkedHashMap)

        性能比HashSet差一点,因为要维护一个双向链表,初始容量与迭代无关,因为迭代的是那个双向链表

    根据实际场景选择

  • 如果是key-value型(映射)

    map中key是唯一的 值是可重复的

    • Map 保持插入顺序的 选择LinkedHashMap

      底层是 散列表和双向链表,允许为空 不同步 插入顺序有序(因为单链表所以致使有序)

      装载因子和初始容量对LinkedHashMap影响挺大的

      初始容量对遍历没有影响,因为它遍历的是LinkedHashMap内部维护着的一个双向链表,而不是一个散列表

      还可以设置两种遍历顺序,访问顺序和插入顺序,访问顺序,就是如果get一个key之后,那个key就会放到map的最后面了

      默认创建的map都是插入顺序,除非创建的时候加个true,就是访问顺序了。

    • 不需要保持顺序就HashMap

      关于HashMap:无序,允许为空,非同步,底层散列表(哈希表)实现

      他还有一个装载因子这个东西,默认是0.75,有什么用呢,就是当装载因子*初始容量小于散列表元素时,该散列表会再散列,扩容2倍

      初始容量默认16

      HashTable有点过时了,我们需要到线程安全的地方可以使用ConCurrentHashMap

    • 对排序有要求 TreeMap

      为什么有序的?

      因为TreeMap实现了NavigableMap接口,而这个接口继承了SortedMap接口,所以TreeMap就是有序的了

      TreeMap底层是红黑树 方法的时间复杂度都不会太高:log(n)

      非同步的

      使用Comparator或者Comparable来比较key是否相等以及排序相关问题,只要这两个方法认为相等或者谁大谁小,然后TreeMap会听这两个方法的结果来进行排序的

      如果构造方法传递了Comparator对象,就会以Comparator对象的方法进行分比较,否则就用Comparable的compareTo来进行比较

      几个要点:

      1. 底层红黑树,时间复杂度log(n)
      2. key不能为null,否则会空指针异常
      3. 想要自定义比较,在构造方法的时候传入Comparator对象即可,否则会按照自然顺序来比较(1,2,3,4,5...)
      4. TreeMap非同步 想要同步可以使用Collections来封装
      
    • ConCurrentHashMap

      JDK1.8底层是散列表+红黑树 JDK1.7是segments+HashEntry数组

      支持高并发的访问和更新,线程安全

      检索操作不用加锁,get方法是非阻塞的

      key和value都不能为空

      有了HashTable为什么还需要这个?

      因为HashTable是在每个方法上都加了Synchronize完成同步,效率低,这个是通过部分加锁和利用CAS算法来实现同步

      Volatile关键字,能保证变量对所有线程可见性(能让所有线程都知道此变量被修改了),但不能保证原子性(修改的过程中在jvm中分好几步,是不安全的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值