java List的4种实现类
java List的4种实现类
以下都是个人理解的描述
ArrayList
- ArrayList是我们在java开发过程中最常见的一种List实现类,属于线程不安全,读取速度快的一种List实现类。也是java入门时最常用的实现类。
- 其中最重要的三个参数即如下代码所示,初始数组增量和一个数组
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final int DEFAULT_CAPACITY = 10;
transient Object[] elementData;
private int size;
...
}
- 因为ArrayList采用的是数组的方式实现,所以其取值速度快,插入碰到扩容问题时速度会减慢,主要原因可以看如下代码
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
初始化:
1.初始化数组长度,小于零就抛出异常,传0则与不传参是一样的
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
2.Collection子类初始化,存在空指针风险,数据利用Array.copyOf进行拷贝
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
this.elementData = EMPTY_ELEMENTDATA;
}
}
3.无参初始化,就是赋予一个空数组,利用扩容做初始化长度
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
最大数组长度:
0x7fff ffff(即Integer的最大长度)或0x7fff ffff – 8
数组增长:
第一次默认增长10,一般情况下向右位移一1位,即以每次以当前数据长度的0.5倍增长
当数组长度达到临界点,增长超过了0x7fff ffff -8时,数组最大长度为0x7fff ffff
sort方法:
利用Array中采用的TimSort二分归并排序方法,注意实现 Comparable接口推荐区分1,-1,0三种情况
Vector
和ArrayList基本相似,利用数组及扩容实现List,但Vector是一种线程安全的List结构,它的读写效率不如ArrayList,其原因是在该实现类内在方法上加上了同步关键字,如
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
return elementData(index);
}
其不同之处还在于Vector的增长速度不同,如下
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
private void ensureCapacityHelper(int minCapacity) {
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
可以看出Vector在默认情况下是以两倍速度递增
所以capacityIncrement可以用来设置递增速度,因此Vector的初始化多了一种方式,即设置数组增量
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
public Vector() {
this(10);
}
LinkedList
- LinkedList是利用内部类Node为数据单元的双向链表,同样LinkedList是线程不安全的,其具有读效率低,写效率高,操作效率高等特性,适合用于频繁add,remove等操作的List,同时可以节省一定的内存,在clear的情况下推荐使用GC回收,并且没有最大长度限制。
- 可以看出双向链表的节点操作没有扩充的拷贝操作,在这种情况下操作相对于反复扩容效率要高,但也仅是相对的,但是有大量数据操作,特别是删除等,只需要做节点的横向移动,效率是很高的。
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
transient Node<E> first;
transient Node<E> last;
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
...
}
当然LinkedList没有预留排序接口
Stack
- 继承于Vector,基本特性与Vector一致,线程安全,但效率低,实际就是利用Vector抽象成栈,使之拥有后进先出的特性
PS.
二分归并算法:
就是通过二分的方式将问题拆分到原子问题,然后通过问题的解决和归并,进行排序,例如将一组随机数拆分利用二分法拆分成多组进行排序,合并时排序,合并完成后,排序也就完成了

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
使用Lambda表达式与回调函数简化缓存操作
1. 缓存操作流程 对一些写低频,读高频的数据操作我们经常需要用到缓存,通常的缓存操作流程如下: 2. 通常的缓存处理方式 通常我们对上面流程的实现,伪代码如下: public Object getObject(String key) { //1. 尝试从缓存读取 Object obj = readFromCache(key); //缓存命中直接返回 if (obj != null) { return obj; } //2.如果缓存未命中,读数据库 obj = readFromDB(); //3. 回写入缓存,并返回 saveToCache(key,obj); return obj; } 对于不同缓存的处理上面步骤1、3是重复的,步骤2是取决
-
下一篇
java EasyExcel集成及工具类使用
EasyExcel简介 easyExcel是阿里巴巴开源poi插件之一,当前最新版本1.1.2-beta5,poi版本3.17,因此,集成时老版本poi需要提升poi版本,或者做版本隔离。 吐槽一下这个版本没有RELEASE版本 主要解决了poi框架使用复杂,sax解析模式不容易操作,数据量大起来容易OOM,解决了POI并发造成的报错 主要解决方式:通过解压文件的方式加载,一行一行的加载,并且抛弃样式字体等不重要的数据,降低内存的占用 具体实现原理,建议看github上的readme EasyExcel优势 注解式自定义操作。 输入输出简单,提供输入输出过程的接口 支持一定程度的单元格合并等灵活化操作 EasyExcel劣势 框架不成熟,1.1.0版本后提供灵活接口的只剩beta版本 依然存在一些bug 没有一套完整的api ExcelUtil快速使用 maven引用(版本控制内若存在低版本POI,请升级版本和代码,官方POI版本3.17): <dependency> <groupId>com.alibaba</groupId> <artifa...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- Docker安装Oracle12C,快速搭建Oracle学习环境
- 面试大杂烩
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS关闭SELinux安全模块
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2全家桶,快速入门学习开发网站教程