文章更新时间:2020/08/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)【在指定位置设置元素】

remove(int index)【删除指定位置的元素】

  总结一下:

  • 检查角标
  • 删除元素
  • 计算出需要移动的个数,并移动
  • 设置为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。

Java基础一篇过(四)List这篇就够了的更多相关文章

  1. Java基础知识常见面试题汇总第一篇

    [Java面试题系列]:Java基础知识常见面试题汇总 第一篇 文中面试题从茫茫网海中精心筛选,如有错误,欢迎指正! 1.前言 ​ 参加过社招的同学都了解,进入一家公司面试开发岗位时,填写完个人信息后 ...

  2. JAVA基础第五章-集合框架Map篇

    业内经常说的一句话是不要重复造轮子,但是有时候,只有自己造一个轮子了,才会深刻明白什么样的轮子适合山路,什么样的轮子适合平地! 我将会持续更新java基础知识,欢迎关注. 往期章节: JAVA基础第一 ...

  3. 【Java面试题系列】:Java基础知识常见面试题汇总 第一篇

    文中面试题从茫茫网海中精心筛选,如有错误,欢迎指正! 1.前言 ​ 参加过社招的同学都了解,进入一家公司面试开发岗位时,填写完个人信息后,一般都会让先做一份笔试题,然后公司会根据笔试题的回答结果,确定 ...

  4. Java基础复习笔记系列 四 数组

    Java基础复习笔记系列之 数组 1.数组初步介绍? Java中的数组是引用类型,不可以直接分配在栈上.不同于C(在Java中,除了基础数据类型外,所有的类型都是引用类型.) Java中的数组在申明时 ...

  5. Java基础——GUI编程(四)

    继前面的,这篇主要记录菜单和文件对话框的两个小练习,来熟悉一下方法的应用,一些简单的逻辑和Swing的相关简介,以及关于GUI基础的记录. 一.创建一个菜单 import java.awt.FlowL ...

  6. Java基础笔试练习(四)

    1.编译Java Application 源程序文件将产生相应的字节码文件,这些字节码文件的扩展名为( ). A.java B.class C.html D.exe 答案: B 解析: Java源程序 ...

  7. Java基础知识笔记(四:多线程基础及生命周期)

    一.多线程基础 编写线程程序主要是构造线程类.构造线程类的方式主要有两种,一种是通过构造类java.lang.Thread的子类,另一种是通过构造方法实现接口java.lang.Runnable的类. ...

  8. JAVA基础学习day22--IO流四-对象序列化、管道流、RandomAccessFile、DataStream、ByteArrayStream、转换流的字符编码

    一.对象序列化 1.1.对象序列化 被操作的对象需要实现Serializable接口 1.2.对象序列化流ObjectOutputStream与ObjectInputStream ObjectInpu ...

  9. Java基础知识拾遗(四)

    IO SequenceInputStream,允许链接多个InputStream对象.在操作上该类从第一个InputStream对象进行读取,知道读取完全部内容,然后切换到第二个InputStream ...

  10. Java基础笔记(十四)——封装

    封装(好比ATM机) 将类的某些信息隐藏在类内部,不允许外部程序直接访问(隐藏对象的信息),通过该类提供的方法来实现对隐藏信息的操作和访问(留出访问的接口). 特点: 1.只能通过规定的方法访问数据. ...

随机推荐

  1. JDBC理论知识

    JDBC理论知识 JDBC基础 JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统.通用的SQL数据库存取和操作的公共接口(一组API), 定义了用来访问数 ...

  2. Docker入门教程-Linux环境安装Nginx及入门使用

    介绍 Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的 Web和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服 ...

  3. 第七篇 Scrum冲刺博客

    一.会议图片 二.任务完成情况 成员 已完成 冯荣新 博客撰写 陈泽佳 自定义图片组件,提交功能 徐伟浩 协助前端获取数据 谢佳余 搜索算法设计 邓帆涛 意见反馈 三.部分代码 <tabs ta ...

  4. APEX安装

    git clone https://github.com/NVIDIA/apex.gitcd apex export CUDA_HOME=/usr/local/cudapip3 install -v ...

  5. python编程入门笔记

    一.作用域 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我们要理解两点: a.在全局不能访问到局 ...

  6. JacaScript实现call apply bind函数

    一.call函数 模拟实现第一步:整体思路 Function.prototype.call2=function(context){ context.fn=this; //1.将函数(谁调用 即this ...

  7. 使用Apache的反向代理会影响搜索引擎的收录和排名吗

    http://www.wocaoseo.com/thread-292-1-1.html 百度官方观点:Baiduspider对站点的抓取方式和普通用户访问一样,只要普通用户能访问到的内容,我们就能抓取 ...

  8. ArcGIS Pro 二次开发

    本文基于 Windows7 + VS2019 + .NET Framework 4.8 + ArcGIS Pro 2.5.22081 开发和撰写. 目录 开发环境配置 获取ArcGIS Pro 安装V ...

  9. slua中,绑定lua文件到Monobehavior的一种方法

    slua本身并不提供如何把一个lua文件绑定到一个预制中,就像一个普通的继承自monobehavior的自定义脚本那样,而tolua的框架却采用了拙劣的做法: public class LuaBeha ...

  10. 合并模拟器和真机的静态库动态库aggregate

    创建Aggregate的target 在Build Phases 添加Run Script,内容为 scriptFile=${SRCROOT}/universalA.shsh ${scriptFile ...