Java基础一篇过(四)List这篇就够了
文章更新时间: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这篇就够了的更多相关文章
- Java基础知识常见面试题汇总第一篇
[Java面试题系列]:Java基础知识常见面试题汇总 第一篇 文中面试题从茫茫网海中精心筛选,如有错误,欢迎指正! 1.前言 参加过社招的同学都了解,进入一家公司面试开发岗位时,填写完个人信息后 ...
- JAVA基础第五章-集合框架Map篇
业内经常说的一句话是不要重复造轮子,但是有时候,只有自己造一个轮子了,才会深刻明白什么样的轮子适合山路,什么样的轮子适合平地! 我将会持续更新java基础知识,欢迎关注. 往期章节: JAVA基础第一 ...
- 【Java面试题系列】:Java基础知识常见面试题汇总 第一篇
文中面试题从茫茫网海中精心筛选,如有错误,欢迎指正! 1.前言 参加过社招的同学都了解,进入一家公司面试开发岗位时,填写完个人信息后,一般都会让先做一份笔试题,然后公司会根据笔试题的回答结果,确定 ...
- Java基础复习笔记系列 四 数组
Java基础复习笔记系列之 数组 1.数组初步介绍? Java中的数组是引用类型,不可以直接分配在栈上.不同于C(在Java中,除了基础数据类型外,所有的类型都是引用类型.) Java中的数组在申明时 ...
- Java基础——GUI编程(四)
继前面的,这篇主要记录菜单和文件对话框的两个小练习,来熟悉一下方法的应用,一些简单的逻辑和Swing的相关简介,以及关于GUI基础的记录. 一.创建一个菜单 import java.awt.FlowL ...
- Java基础笔试练习(四)
1.编译Java Application 源程序文件将产生相应的字节码文件,这些字节码文件的扩展名为( ). A.java B.class C.html D.exe 答案: B 解析: Java源程序 ...
- Java基础知识笔记(四:多线程基础及生命周期)
一.多线程基础 编写线程程序主要是构造线程类.构造线程类的方式主要有两种,一种是通过构造类java.lang.Thread的子类,另一种是通过构造方法实现接口java.lang.Runnable的类. ...
- JAVA基础学习day22--IO流四-对象序列化、管道流、RandomAccessFile、DataStream、ByteArrayStream、转换流的字符编码
一.对象序列化 1.1.对象序列化 被操作的对象需要实现Serializable接口 1.2.对象序列化流ObjectOutputStream与ObjectInputStream ObjectInpu ...
- Java基础知识拾遗(四)
IO SequenceInputStream,允许链接多个InputStream对象.在操作上该类从第一个InputStream对象进行读取,知道读取完全部内容,然后切换到第二个InputStream ...
- Java基础笔记(十四)——封装
封装(好比ATM机) 将类的某些信息隐藏在类内部,不允许外部程序直接访问(隐藏对象的信息),通过该类提供的方法来实现对隐藏信息的操作和访问(留出访问的接口). 特点: 1.只能通过规定的方法访问数据. ...
随机推荐
- Nginx进阶使用-负载均衡原理及配置实例
介绍 跨多个应用程序实例的负载平衡是一种用于优化资源利用率,最大化吞吐量,减少延迟和确保容错配置的常用技术.可以将Nginx用作非常有效的HTTP负载平衡器,以将流量分配到多个应用程序服务器,并使用N ...
- windows操作报错:无法启动此程序,因为计算机中丢失api-ms-win-core-winrt-string-l1-1-0.dll
在Windows上做提交svn操作时报错:无法启动此程序,因为计算机中丢失api-ms-win-core-winrt-string-l1-1-0.dll,如下图: 解决办法: 在 https://cn ...
- 快速排序算法简述及python的实现
def kp(arr, i, j): if i<j: #i=j时意味着一边只剩单个数据 base = kpgc(arr, i, j) kp(arr, i, base-1) #kp(arr, i, ...
- 从开源协议到谷歌禁用华为、Docker实体清单事件
平时我们在日常开发生活都在大量和开源软件打着交道,例如安卓.Linux.Github.Docker等,而其中开源协议比如MIT.Apache也是耳熟能详,但是真正对开源协议的了解相信对大部分人来说都 ...
- python数据类型和运算符
一.python类型判断 type,isinstance type(变量或常量):返回数据类型 a = 23.3print(type(a))b = 2e3print(b, type(b))输出: &l ...
- Git的详细使用
关于Git的详细使用,下面博主的博客写的非常的详细! 可以参考一下. https://blog.csdn.net/qq_19835247/article/details/104620042 人生需要准 ...
- go微服务系列(四) - http api中引入protobuf
1. protobuf相关依赖安装 2. 改造之前的client 2.1 新建proto文件 2.2 运行protoc命令生成go文件 2.3 然后把原来的map修改成具体的类型就可以了 3. 处理j ...
- day42:HTML标签和CSS选择器
目录 1.HTML 1.1 文档结构 1.2 head标签 1.3 body标签 1.3.1 h1-h6标签 1.3.2.br标签:换行 1.3.3.hr标签:一行横线 1.3.4 a标签:超链接标签 ...
- [apue] 一图读懂 unix 文件句柄及文件共享过程
与文件相关的一些概念 在开始上图之前,先说明几个和 unix 文件密切相关的术语,方便后续讨论使用 文件句柄 / 文件描述符 (file descriptor 或 FD):描述一个打开文件相关属性的类 ...
- Java学习笔记——java基础
2020.9.1 学习来自 https://www.liaoxuefeng.com/wiki/1252599548343744/1255883729079552 一.变量和数据类型 基本数据类型 基本 ...