• Java基础一篇过(四)List这篇就够了


    文章更新时间:2020/03/03

    一、List介绍

      list是Java的一个接口,继承了Collection,常用到的有3个子类实现:

    • ArrayList
      • 底层数据结构是数组线程不安全
    • LinkedList
      • 底层数据结构是链表线程不安全
    • Vector
      • 底层数据结构是数组线程安全

    下面就这3个常用子类进行分析学习。

    二、ArrayList

      ArrayList位于java.util包下,由于英文水平有限,且注释又全是英文,我把里面的代码copy出来,并用自己的语言来整理并理解ArrayList

    底层实现数组

    特点查询快,增删慢 (因为数组是有索引的,通过下标直接访问)

      属性

     

    构造方法

     

     

    add(E e)【在末尾添加元素】

     

     

       总结一下:首先去检查一下数组的容量是否足够

    • 不足够扩容
      • 扩容到原来的1.5倍
      • 第一次扩容后,如果容量还是小于minCapacity,就将容量扩充为minCapacity。
    • 足够直接添加

    add(int index, E element)【在指定位置添加元素】

     

       PS:与扩容相关ArrayList的add方法底层其实都是arraycopy()来实现的看到arraycopy(),我们可以发现:该方法是由C/C++来编写的,并不是由Java实现

    get(int index)【获取指定位置的元素】

     

    set(int index, E element)【在指定位置设置元素】

     

       总结一下:

    • 检查角标
    • 删除元素
    • 计算出需要移动的个数,并移动
    • 设置为null,让Gc回收原来的对象

      PS:删除元素时不会减少容量,若希望减少容量则调用trimToSize()

    小结

    • ArrayList是基于动态数组实现的,在增删时候,需要数组的拷贝复制
    • ArrayList的默认初始化容量是10每次扩容时候增加原先容量的一半,也就是变为原来的1.5倍
    • 删除元素时不会减少容量,若希望减少容量则调用trimToSize()
    • 不是线程安全的
    • 它能存放null值
    • indexOf和lastIndexOf方法查找元素,若元素不存在,则返回-1

    三、LinkedList

    简介

      LinkedList也位于java.util包下,底层实现为链表。

    底层实现: 线性链表

      特点增删快,查询慢(因为是链表结构,没有初始化大小,也没有扩容的机制,只用考虑在前面还是后面进行操作。)

    PS:JDK1.5之前采用单向链表, JDK1.5之后采用双向链表

    简单认识一下链表:

       链表结构中的每一个元素为Node对象,添加元素的时候实际上是对Node的操作:

    属性

    构造方法

      构造方法主要都是根据入参来循环设置每一个Node对象的prev(前一个对象)和next(后一个对象),感兴趣的话可以看下底层的代码实现,这里就不详细写了

    add【添加节点】

     

    图示:

     

    remove【删除节点】

     

     

     unlink图示:

    get【获取节点】set【设置节点】

      原理都是查看角标是否大于长度的一半,若大于则从尾部遍历并操作元素,小于则从头部遍历并操作元素。(具体代码就不详细图解了)

    小结

    • LinkedList的没有扩容方法,默认从尾部加入元素就是自动扩容
    • LinkedList是基于链表实现的,因此增删改效率高,查询效率低

    四、Vector

    底层实现: 数组

      特点线程安全,但消耗内存,效率不高(因为方法都加了synchronized关键字。)

    Vector与ArrayList异同:

    • Vector底层也是数组,与ArrayList最大的区别就是:同步(线程安全)
    • 想要ArrayList实现同步,可以使用Collections的方法:List list = Collections.synchronizedList(new ArrayList());
    • ArrayList在底层数组不够用时在原来的基础上扩展0.5倍Vector扩展1倍
    • 大部分非多线程安全的场景下我们都使用ArrayList和LinkedList,现vector已基本废弃。

    五、总结

    ArrayList

    • 底层实现是数组
    • ArrayList的默认初始化容量是10每次扩容时候增加原先容量的一半,也就是变为原来的1.5倍
    • 在增删时候,需要数组的拷贝复制(navite 方法由C/C++实现)

    LinkedList

    • 底层实现是双向链表(1.5以后的版本,之前的是单向链表)

    Vector

    • 底层是数组,现在已较少使用
    • Vector所有方法都加了synchronized关键字实现同步,同步就意味着有性能损失
    • Vector初始length是10,超过length时,以100%比率增长,相比于ArrayList消耗更多内存。

      一句话小结:查询多用ArrayList,增删多用LinkedList,同步场景用Vector。

  • 相关阅读:
    操作系统 实验一 命令解释程序的编写
    软件工程 《构建之法》1、2、3章读后感
    软件工程实验一 复利计算 第四次实验
    软件工程实验一 复利计算(第三次实验实验总结)
    软件工程实验一 复利计算
    实验0 了解和熟悉操作系统
    团队工作总结及自评 & 补上来的用户调研
    四则运算安卓版ver.mk2
    安卓版四则运算
    每日更新
  • 原文地址:https://www.cnblogs.com/riches/p/12111644.html
Copyright © 2020-2023  润新知