1. ArrayList

    以数组实现。节约空间,但数组有容量限制。超出限制时会增加50%容量,用System.arraycopy()复制到新的数组。因此最好能给出数组大小的预估值。默认第一次插入元素时创建大小为10的数组。按数组下标访问元素-get(i)、set(i,e)的性能很高,这是数组的基本优势。如果按下标插入元素、删除元素-add(i,e)、remove(i)、remove(e),则要用System.arraycopy()来复制移动部分受影响的元素,性能就变差了。越是前面的元素,修改时要移动的元素越多。直接在数组末尾加入元素-常用的add(e),删除最后一个元素则无影响。

    ArrayList是一个相对来说比较简单的数据结构,最重要的一点就是它的自动扩容。

  2. 构造方法

    ArrayList提供了三个构造方法:

    1. ArrayList(int initialCapacity):指定容量
    2. ArrayList():构造一个默认容量为10的ArrayList
    3. ArrayList(Collection<? extends E> c):构造一个指定Collection的ArrayList
  3. add

    // 添加指定元素到list末尾
public boolean add(E e) {
// 检查是否需要扩容
ensureCapacityInternal(size + 1); // Increments modCount!!
// 赋值
elementData[size++] = e;
return true;
} private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// 比较默认的容量10和传入的容量,返回大点的数
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
//扩容
ensureExplicitCapacity(minCapacity);
} private void ensureExplicitCapacity(int minCapacity) {
// 记录修改次数
modCount++; // overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
} private void grow(int minCapacity) {
// overflow-conscious code
// 记录当前list的容量
int oldCapacity = elementData.length;
// 扩展为原来的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果扩展1.5倍还不能满足,直接扩展为需求值
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);
}

也就是说,当增加数据的时候,如果ArrayList的大小已经不满足需求时,那么数组大小就会变为原来的1.5倍,之后就是把老的数据拷贝新的数组里面。例如我创建的list的容量时10,当我们已经添加了10个元素的之后,再添加就会进行自动扩容到15。

  1. get,set
    public E get(int index) {
rangeCheck(index); return elementData(index);
} public E set(int index, E element) {
rangeCheck(index); E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}

get()和set()就比较简单了,进行范围检查后就可以进行对应的操作了。由于ArrayList是动态数组,所以我们完全可以根据下标来获取ArrayList中的元素,而且速度还比较快,故ArrayList长于随机访问。

  1. remove
    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 work return oldValue;
}

remove()首先进行范围检查,然后计算移动的开始位置,如果大于0的话就进行移动并返回旧值

参考文章:

  1. http://yikun.github.io/2015/04/04/Java-ArrayList工作原理及实现/

【Java基础】ArrayList工作原理的更多相关文章

  1. HTTPS那些事 用java实现HTTPS工作原理

    HTTPS那些事 用java实现HTTPS工作原理 博客分类: java历险   今天被问到关于https原理的问题,结果由于知识掌握不牢靠,停留于表面,很多细节都无法回答清楚,于是决定把https的 ...

  2. 详解Java GC的工作原理+Minor GC、FullGC

    详解Java GC的工作原理+Minor GC.FullGC 引用地址:http://www.blogjava.net/ldwblog/archive/2013/07/24/401919.html J ...

  3. java gc的工作原理、如何优化GC的性能、如何和GC进行有效的交互

    java gc的工作原理.如何优化GC的性能.如何和GC进行有效的交互 一个优秀的Java 程序员必须了解GC 的工作原理.如何优化GC的性能.如何和GC进行有效的交互,因为有一些应用程序对性能要求较 ...

  4. Java Web程序工作原理

    Web开发的最重要的基本功能是HTTP:Java Web开发的最重要的基本功是Servlet Specification.HTTP和Servlet Specitication对于Web Server和 ...

  5. Java基础——ArrayList

    Java基础--ArrayList 作用:提供一个可变长度的集合,底层实际上是一个可变长度的数组 格式:ArrayList <E> arr=new ArrayList<>(); ...

  6. Java基础-ArrayList和LinkedList的区别

    大致区别:  1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构. 2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为Lin ...

  7. 【Java】Servlet 工作原理解析

    Web 技术成为当今主流的互联网 Web 应用技术之一,而 Servlet 是 Java Web 技术的核心基础.因而掌握 Servlet 的工作原理是成为一名合格的 Java Web 技术开发人员的 ...

  8. java程序的工作原理

    Sun公司设计java语言的目标是让Java程序不必经过修改就可以在各种各样的计算机(包括PC机和工作站)上运行.为了实现这一目标,Sun公司提供了一阵Java虚拟机(Java Virtual Mac ...

  9. Java基础ArrayList、Servlet与Filter

    一.技术分享 迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为"轻量级"对象,因 ...

随机推荐

  1. delphi的TFileStream 内存流

    一.文件 文本文件是以行为单位进行读.写操作的.文本文件只能单独为读或写而打开,在一个打开的文本文件上同时进行读.写操作是不允许的. 二.定义 FileStream: TFileStream; 三.打 ...

  2. ViewFlipper的功能与用法

    ViewFlipper组件继承了ViewAnimator,它可调用addView(View v)添加多个组件,一旦向ViewFlipper中添加了多个组件之后,ViewFlipper可使用动画控制多个 ...

  3. HTML最基础的入门(上)

    一.互联网原理 互联网原理:上网即请求数据. 过程:在本机计算机浏览器上输入网址,发送一个http请求到服务器端,服务器会根据协议作出响应,将对应的网页文件通过http协议再传输给我们本地计算机,将网 ...

  4. Failed to register Grid Infrastructure type ora.mdns.type

    安装11g的集群软件的时候,在最后运行root.sh脚本时候,没有执行成功,最后提示如下错误: [root@r2 ~]# /u01/app/11.2.0/grid_1/root.sh Performi ...

  5. JSP EL表达式 param、paramValues的使用

    JSP EL表达式 param.paramValues的使用: <%@ page language="java" import="java.util.*" ...

  6. spring mvc 注解示例

    springmvc.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...

  7. Ninja介绍

    什么是Ninja 在Unix/Linux下通常使用Makefile来控制代码的编译,但是Makefile对于比较大的项目有时候会比较慢,看看上面那副漫画,代码在编译都变成了程序员放松的借口了.所以这个 ...

  8. 第三章 Python 的容器: 列表、元组、字典与集合

    列表是Python的6种内建序列(列表,元组,字符串,Unicode字符串,buffer对象,xrange对象)之一, 列表内的值可以进行更改,操作灵活,在Python脚本中应用非常广泛 列表的语法格 ...

  9. 3D游戏开发之在UE4中创建非玩家角色(NPC)

    接着上节我们继续学习,现在我们来创建一些NPC(non-playable characters,非玩家角色).在这个游戏中,当我们靠近NPC时,它们会做出相应的反应. 一 创建C++类 1) 在UE编 ...

  10. 如何使用DockerHub官方的mysql镜像

    Mysql是一个广泛使用的开源关系型数据库. 如何获取Mysql Docker镜像? docker pull mysql:5.7 如何使用这个Docker镜像? 1.启动一个Mysql Server容 ...