zoukankan      html  css  js  c++  java
  • 单列集合List

    Vector和ArrayList以及LinkedList区别和联系,以及分别的应用场景

      线程安全:

        Vector:如果创建Vector时没有指定容量,则默认容量为10,底层基于数组实现,线程是安全的,底层采用synchronized同步方法进行加锁

        ArrayList:底层基于数组,线程不安全,查询和修改效率高,但是增加和删除效率低

        LinkedList:底层双向链表结构,线程不安全,查询和修改效率低,但是增加和删除效率高

      使用场景:

        Vector很少用

        如果需要大量的添加和删除则可以选择LinkedList

        如果需要大量的查询和修改则可以选择ArrayList

    ArrayList和LinkList的区别

      ArrayList和LinkedList,ArrayList是一个动态数组,LinkedList是一个双向链表结构,都是实现了List接口;

      当随机访问集合中的元素时,ArrayList比LinkedList的效率高,因为LinkedList时线性的数据存储方式,需要移动指针从前往后一次查找;

      当对集合元素进行增删操作时,LinkedList比ArrayList效率高,因为ArrayList是数组,所以在进行增删操作时,会对操作点之后的所有元素的下标索引造成影响,需要进行元素的移动;

      从利用效果来讲:ArrayList自由性比较低,需要设置固定大小容量,但是使用比较方便,只需要创建然后添加元素,通过下标索引进行使用。

      而LinkedList自由性较高,可以动态的随元素的变化而变化,但是不便于使用;

      ArratList需要在List列表预留一定空间;而LinkedList需要存储结点信息以及结点指针信息


    如果要保证ArraList线程安全,有几种方式?

      自己表写一个ArrayList集合类,根据业务一般来说,add/set/remove加锁

      利用List<Object> list = Collections.synchronizedList(new ArrayList<>()); //采用synchronized加锁

       new CopyOnWriteArrayList<>().add(""); //采用 ReentrantLock加锁


    了解CopyOnWriteArrayList底层?,CopyOnWriteArrayList与Collections.synchronizedList有什么区别

      CopyOnWriteArrayList底层实现:

        CopyOnWriteArrayList在执行修改操作的时候,会复制一份新的数组数据,代价昂贵,修改过后将原来的集合指向到新的集合完成操作

        使用ReentrantLock保证多线程环境下的集合安全

      

    public boolean add(E e) {
    
        final ReentrantLock lock = this.lock;      //获取了一把锁
    
        lock.lock();                    //加锁
    
        try {
    
          Object[] elements = getArray();        //获取当前数组数据,给elements
    
          int len = elements.length;          //记录当前数组的长度
    
          Object[] newElements = Arrays.copyOf(elements, len + 1);     //复制一个新的数组
    
          newElements[len] = e;             //将数据填入到新数组当中
    
          setArray(newElements);           //将当前array指针指向到新的数据
    
          return true;
    
        } finally {
    
          lock.unlock();                //释放锁
    
        }
    
      }
    

      

      CopyOnWriteArrayList应用场景:适用于读取操作远大于写操作场景(底层get读取时没有加锁,直接获取)


      Collections.synchronizedList几乎底层方法都加上了synchronized的锁
      场景:写操作的性能比CopyOnWriteArrayList要好,但是读取的性能不如CopyOnWriteArrayList


    CopyOnWriteArrayList设计思想是怎么样的,有什么缺点?

      设计思想:读写分离,最终一致

      缺点:内存占用,由于写时复制,内存中就会出现两个对象占用空间,如果对象大则容易发生YongGC和FullGC


    说一下ArrayList扩容机制是怎么样的

      ArrayList是List接口的实现类,它是支持根据需要而动态增长的数组。

      java中标准数组是定长的,在数组被创建之后,它们不能被加长或缩短。

      这就意味着在创建数组时需要知道数组的所需长度,但有时我们需要动态程序中获取数组长度。ArrayList就是为此而生的。

      1.7 以及之前版本JDK,首先从默认大小来讲,默认为10

      1.8 ArrayList集合大小如果创建时没有指定,则默认为0,若已经指定集合大小,则初始值为指

      当第一次添加数据的时候,集合大小扩容为10

      第二次及其后续每次按照int oldCapacity = elementData.length; newCapacity = oldCapacity+(oldCapacity>>1)

    手写ArrayList集合框架
     

     //代表集合真正存储的数据
      private transient Object [] elementData;
      //代表默认情况下,创建集合时,是一个空数组
      private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
      //当前集合大小
      private Integer size;
      //默认初始容量
      private static final Integer DEFAULT_CAPACITY=10;
        创建一个ArrayList首先通过构建MyArrayList
    
      public MyArrayList(){
      //创建一个空数组
      this.elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
      }
      public MyArrayList(int initalCapaCity){
      if(initalCapaCity>0){
        this.elementData=new Object[initalCapaCity];
      }else if(initalCapaCity==0){
        this.elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
      }else{
        throw new IllegalArgumentException("参数错误");
      }
    }
    

      /

  • 相关阅读:
    windows下安装mysql教程
    git基本操作
    JDK8,Optional
    重新安装MySQL 8出现的问题
    HTML5学习:缩略图
    HTML5学习:表格
    MySQL常用命令
    Django学习:创建admin后台管理站点
    Django学习:连接Mysql数据库
    Django学习:创建第一个app
  • 原文地址:https://www.cnblogs.com/F017/p/12499453.html
Copyright © 2011-2022 走看看