【一天一个基础系列】- java之集合篇(下) | 七日打卡

144 阅读4分钟

简介

  • 前面已经列举了几个常用的集合类,接下来继续其他集合类的分析
    • List集合
      • List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引
      • List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素
      • List集合默认按元素的添加顺序设置元素的索引
    • ArrayListVector实现类
      • ArrayListVector作为List类的两个典型实现,完全支持前面介绍的List接口的全部功能
      • ArrayListVector对象使用initialCapacity参数来设置该数组的长度,当向ArrayListVector中添加元素超出了该数组的长度时,它们的initialCapacity会自动增加
      • 一开始就知道ArrayListVector集合需要保存多少个元素,则可以在创建它们时就指定initialCapacity大小
      • 创建空的ArrayListVector集合时不指定initialCapacity参数,则Object[]数组的长度默认为10
      • ArrayListVector还提供了如下两个方法来重新分配Object[]数组
        • void ensureCapacity(int minCapacity):将ArrayListVector集合的Object[]数组长度增加大于或等于minCapacity值
        • void trimToSize():调整ArrayListVector集合的Object[]数组长度为当前元素的个数。调用该方法可减少ArrayListVector集合对象占用的存储空间
      • ArrayListVector的显著区别是
        • ArrayList是线程不安全的,Vector是线程安全的(里面的方法都加了锁)

      注意:如果向ArrayListVector集合中添加大量元素时,可使用ensureCapacity(int minCapacity)方法一次性地增加initialCapacity。这可以减少重分配的次数,从而提高性能

    • 固定长度的List
      • Arrays,该工具类里提供了asList(Object...a)方法,该方法可以把一个数组或指定个数的对象转换成一个List集合,这个List集合既不是ArrayList实现类的实例,也不是Vector实现类的实例,而是Arrays的内部类ArrayList的实例

      注意:Arrays.ArrayList是一个固定长度的List集合,程序只能遍历访问该集合里的元素,不可增加、删除该集合里的元素,否则引发UnsupportedOperationException异常

    • Queue集合
      • Queue用于模拟队列这种数据结构,队列通常是指“先进先出”(FIFO)的容器
      • 实现类
        • PriorityQueue实现类
          • PriorityQueue保存队列元素的顺序并不是按加入队列的顺序,而是按队列元素的大小进行重新排序
          • PriorityQueue不允许插入null元素,它还需要对队列元素进行排序,PriorityQueue的元素有两种排序方式
            • 自然排序:采用自然顺序的PriorityQueue集合中的元素必须实现了Comparable接口,而且应该是同一个类的多个实例,否则可能导致ClassCastException异常。
            • 定制排序:创建PriorityQueue队列时,传入一个Comparator对象,该对象负责对队列中的所有元素进行排序。采用定制排序时不要求队列元素实现Comparable接口。
    • Deque接口
      • Deque接口的实现类:ArrayDeque是一个基于数组实现的双端队列
    • LinkedList实现类
      • LinkedList类是List接口的实现类
      • LinkedList还实现了Deque接口,可以被当成双端队列来使用,因此既可以被当成“栈”来使用,也可以当成队列使用
    • LinkedListArrayListArrayDeque对比
      • ArrayListArrayDeque内部以数组的形式来保存集合中的元素,因此随机访问集合元素时有较好的性能
      • LinkedList内部以链表的形式来保存集合中的元素,因此随机访问集合元素时性能较差,但在插入、删除元素时性能比较出色
    • Map集合
      • Map用于保存具有映射关系的数据,因此Map集合里保存着两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的valuekeyvalue都可以是任何引用类型的数据
      • Mapkey不允许重复,即同一个Map对象的任何两个key通过equals方法比较总是返回false
      • 实现类
        • HashMapHashtable
          • Hashtable是一个线程安全的Map实现,但HashMap是线程不安全的实现,所以HashMapHashtable的性能高一点;但如果有多个线程访问同一个Map对象时,使用Hashtable实现类会更好
          • Hashtable不允许使用null作为keyvalue,如果试图把null值放进Hashtable中,将会引发NullPointerException异常;但HashMap可以使用null作为keykey不能重复,故只能有一个keynull)或value
        • 讲到HashMap,不得不提其是一个线程不安全的容器,在多线程环境下, 使HashMapput操作会引起死循环, 导致CPU利率接近100%, 所以在并发情况下不能使用HashMap
          • 原因:是因为多线程会导致HashMapEntry链表形成环形数据结构,一旦形成环形数据结构,Entrynext节点永远不为空,就会产死循环获取Entry
    • 总结:在使用集合的时候,要全面对比各个实现类的特性,才能更好的运用,发挥最大的性能。