1. 数据结构--ArrayList源码摘要

ublic class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{private static final long serialVersionUID = 8683452581122892189L;/*** Default initial capacity.*/private static final int DEFAULT_CAPACITY = 10;/*** Shared empty array instance used for empty instances.*/private static final Object[] EMPTY_ELEMENTDATA = {};/*** The array buffer into which the elements of the ArrayList are stored.* The capacity of the ArrayList is the length of this array buffer. Any* empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to* DEFAULT_CAPACITY when the first element is added.*/private transient Object[] elementData;/*** The size of the ArrayList (the number of elements it contains).** @serial*/private int size;
}

ArrayList 的底层最重要的两个属性:Object 数组和 size 属性。

2. ArrayList 的底层数组的调整

add方法--ArrayList源码摘要

/*** Appends the specified element to the end of this list.** @param e element to be appended to this list* @return <tt>true</tt> (as specified by {@link Collection#add})*/public boolean add(E e) {ensureCapacityInternal(size + 1);  // Increments modCount!!elementData[size++] = e;return true;}

grow方法--ArrayList源码摘要

/**

* Increases the capacity of this <tt>ArrayList</tt> instance, if

* necessary, to ensure that it can hold at least the number of elements

* specified by the minimum capacity argument.

*

* @param   minCapacity   the desired minimum capacity

*/

public void ensureCapacity(int minCapacity) {

int minExpand = (elementData != EMPTY_ELEMENTDATA)

// any size if real element table

? 0

// larger than default for empty table. It's already supposed to be

// at default size.

: DEFAULT_CAPACITY;

if (minCapacity > minExpand) {

ensureExplicitCapacity(minCapacity);

}

}

private void ensureCapacityInternal(int minCapacity) {

if (elementData == EMPTY_ELEMENTDATA) {

minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);

}

ensureExplicitCapacity(minCapacity);

}

private void ensureExplicitCapacity(int minCapacity) {

modCount++;

// overflow-conscious code

if (minCapacity - elementData.length > 0)

grow(minCapacity);

}

/**

* The maximum size of array to allocate.

* Some VMs reserve some header words in an array.

* Attempts to allocate larger arrays may result in

* OutOfMemoryError: Requested array size exceeds VM limit

*/

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

/**

* Increases the capacity to ensure that it can hold at least the

* number of elements specified by the minimum capacity argument.

*

* @param minCapacity the desired minimum capacity

*/

private void grow(int minCapacity) {

// overflow-conscious code

int oldCapacity = elementData.length;

int newCapacity = oldCapacity + (oldCapacity >> 1);

if (newCapacity - minCapacity < 0)

newCapacity = minCapacity;

if (newCapacity - MAX_ARRAY_SIZE > 0)

newCapacity = hugeCapacity(minCapacity);

// minCapacity is usually close to size, so this is a win:

elementData = Arrays.copyOf(elementData, newCapacity);

}

private static int hugeCapacity(int minCapacity) {

if (minCapacity < 0) // overflow

throw new OutOfMemoryError();

return (minCapacity > MAX_ARRAY_SIZE) ?

Integer.MAX_VALUE :

MAX_ARRAY_SIZE;

}

 

2点结论:

a. ArrayList 是通过将底层 Object 数组复制的方式(System.arraycopy方法)来处理数组的增长;

b. 当ArrayList 的容量不足时,其扩充容量的方式:先将容量扩充至当前容量的1.5倍,若还不够,则将容量扩充至当前需要的数量(grow方法)。

remove 方法--ArrayList源码摘要

/*** Removes the element at the specified position in this list.* Shifts any subsequent elements to the left (subtracts one from their* indices).** @param index the index of the element to be removed* @return the element that was removed from the list* @throws IndexOutOfBoundsException {@inheritDoc}*/public E remove(int index) {rangeCheck(index);modCount++;E oldValue = elementData(index);int numMoved = size - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData[--size] = null; // clear to let GC do its workreturn oldValue;}

  

/**

* Removes the first occurrence of the specified element from this list,

* if it is present.  If the list does not contain the element, it is

* unchanged.  More formally, removes the element with the lowest index

* <tt>i</tt> such that

* <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>

* (if such an element exists).  Returns <tt>true</tt> if this list

* contained the specified element (or equivalently, if this list

* changed as a result of the call).

*

* @param o element to be removed from this list, if present

* @return <tt>true</tt> if this list contained the specified element

*/

public boolean remove(Object o) {

if (o == null) {

for (int index = 0; index < size; index++)

if (elementData[index] == null) {

fastRemove(index);

return true;

}

} else {

for (int index = 0; index < size; index++)

if (o.equals(elementData[index])) {

fastRemove(index);

return true;

}

}

return false;

}

/*

* Private remove method that skips bounds checking and does not

* return the value removed.

*/

private void fastRemove(int index) {

modCount++;

int numMoved = size - index - 1;

if (numMoved > 0)

System.arraycopy(elementData, index+1, elementData, index,

numMoved);

elementData[--size] = null; // clear to let GC do its work

}

 

这也就解释了 ArrayList 的特点:增加、删除和移动元素的效率低(数组复制过程消耗资源较多); 而查找元素和更新元素的效率高。

3. ArrayList与Vector的区别

1) vector 是线程同步的,所以它也是线程安全的,而arraylist 是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用 arraylist效率比较高。

2)如果集合中的元素的数目大于目前集合数组的长度时,vector 增长率为目前数组长度的100%, 而arraylist 增长率为目前数组长度的50% .如果在集合中使用数据量比较大的数据,用vector有一定的优势。

3)如果查找一个指定位置的数据,vector和arraylist使用的时间是相同的,都是O(1) ,这个时候使用vector和arraylist都可以。

而如果移动一个指定位置的数据花费的时间为O(n-i)n为总长度,这个时候就应该考虑到使用linklist ,因为它移动一个指定位置的数据所花费的时间为0(1),而查询一个指定位置的数据时花费的时间为0(i)。

转载于:https://www.cnblogs.com/dassmeta/p/5334960.html

Java 的 ArrayList 的底层数据结构相关推荐

  1. 【Java基础】HashMap底层数据结构及其原理

    1.简单了解一下HashMap HashMap 就是以 Key-Value 键值对的方式进行数据存储的一种数据结构,它在 JDK 1.7 和 JDK 1.8 中底层数据结构是有些不一样的.简单来说,J ...

  2. java中什么是底层数据结构_JavaScript 对象的底层数据结构是什么

    这也是个老生常谈的问题,最近得空也开始总结下这方面的知识点.学过java的同学,都知道java把内存分为两种形式,一种是栈内存,另一种是堆内存.java的基本类型(int,short,long,byt ...

  3. Java集合- HashMap 的底层数据结构实现原理

    一.HashMap 的数据结构 JDK1.8 之前 JDK1.8 之前 HashMap 底层是 数组和链表 结合在一起使用也就是 链表散列. HashMap 通过 key 的 hashCode 经过扰 ...

  4. Java集合—ArrayList底层原理

    原文作者:0 errors 0 warnings 原文地址:用大白话告诉你ArrayList的底层原理 目录 一.数据结构 二.线程安全性 三.继承关系 四.构造方法 五.add()方法 六.扩容机制 ...

  5. ArrayList的底层实现原理

    ArrayList源码分析 1.java.util.ArrayList<E> : List 接口的大小可变数组的实现类 ArrayList 内部基于 数组 存储 各个元素. 所谓大小可变数 ...

  6. 深入Java集合ArrayList的源码解析

    现在由大恶人付有杰来从增删改查几个角度轻度解析ArrayList的源码 首先ArrayList的底层数据结构非常简单,就是一个数组. 从源码第115行我们可以得出信息,他的默认数组长度是10. /** ...

  7. ArrayList 集合底层实现原理解析

    文章目录 1. ArrayList 集合底层数据结构 1. ArrayList 集合介绍 2. 数组结构介绍 2. ArrayList 继承关系 2.1 Serializable 标记性接口 2.2 ...

  8. 【java版数据结构】看完数据结构的顺序结构后,紧接着去实现ArrayList的底层(150行代码,数组扩容,增删改查,但未实现迭代器)

    实现效果: 需求分析: 可以看到ArrayList容器有很多功能,在指定位置添加元素,在容器末尾添加元素,获取指定位置的元素,获取容器的大小,清空容器的元素,判断容器是否是空的,删除指定位置的元素,删 ...

  9. Java基础(19)数据结构概述、ArrayList集合、Vector集合、LinkedList集合、集合框架练习

    1. 数据结构概述 1. 数据结构的概述:数据结构就是数据存储的方式 2. 常见数据结构:栈,队列,数组,链表,二叉树,哈希表 3. 栈和队列 (1)栈:先进后出,后进先出 (2)队列:先进先出,后进 ...

最新文章

  1. 如何“快”、“准”、“狠”成为优秀算法工程师
  2. 黄聪:C# MP3操作类,能播放指定的mp3文件,或播放嵌入的资源中的Mp3文件
  3. 对于Array的引用
  4. QtQuick 中的 qml 与 Qt 的 C++
  5. springboot jwt token前后端分离_「转」七个开源的 Spring Boot 前后端分离项目,建议收藏加转载...
  6. MATLAB调用C/C++函数的方法
  7. I/O设备的编址方式(统一编址,独立编址)
  8. activeMQ入门安装
  9. C++容器,迭代器,容器的适配器
  10. 跨过虚拟化技术浪潮,这家企业快步入局云数据管理​
  11. Android viewpager 嵌套 viewpager滑动 点击事件冲突解决方案
  12. 有序表的索引顺序结构查找次数分析
  13. 敏捷无敌之Gitlab CI实战
  14. 步进电机代替舵机方案
  15. QT之如何添加现有文件
  16. 苹果手机上网很慢_手机4G信号满格,上网速度却很慢?原来都是它们在“搞鬼”...
  17. MySQL安装QT连接MySQL学习记录
  18. 关于vue-cli3的浏览器兼容性
  19. 小甲鱼零基础学习python_19 【pickle -- 腌制一缸泡菜】
  20. android第三方上传文件,安卓和苹果终于打通!互传文件无需借助第三方,一碰就能传...

热门文章

  1. h.264并行解码算法分析
  2. 前端大牛or架构师应该具备这些
  3. 安装linux环境及相关包方法
  4. linux下使用source /etc/profile保存配置后,新的环境变量只能在一个终端里面有效...
  5. 当世界从移动优先变为AI优先,未来企业竞争将赢在“维度”
  6. 搭建一个项目的准备工作
  7. strcat与strncat的C/C++实现
  8. 一步一步重写 CodeIgniter 框架 (2) —— 实现简单的路由功能
  9. Ogre:ManualObject
  10. 页面间传值的新思路--PreviousPage