ArrayList源码阅读----JDK1.8
//定义一个默认的长度10
private static final int DEFAULT_CAPACITY = 10;
//定义空的数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//定义数组用来存储放入ArrayList的元素
private transient Object[] elementData;
//定义记录ArrayList中元素的个数
private int size; //构造方法--创建指定长度的数组的ArrayList
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
//创建ArrayList数组长度为0的ArrayList,当向其中添加第一个元素的时候,扩展数组的长度为10--默认数组长度
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}
//创建含有指定集合元素的ArrayList,通过集合的toArray()方法返回一个数组,让ArrayList的数组指向该数组
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
//当ArrayList的元素个数小于数组长度时候,将数组的长度减小为ArrayList中元素的个数
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = Arrays.copyOf(elementData, size);
}
}
// 向ArrayList中添加一个元素,添加前先检查数组的容量,是否需要扩容,再添加元素进去
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
//注意:minCapavity为添加元素时ArrayList需要最小的容量--确定需要的最小容量
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);
} }
//控制内存溢出使用,对最大容量的限制,最大的数组长度为整型最大值减8
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//扩展容量:先根据原来的容量扩展为原来的1.5倍,再和最小需要的容量比较,假如还是比需要的小,则将最小需要的赋值给数组新容量
假如新容量比最大的容量大,则再次扩容,扩容完成后将数组原来的内容,复制到新的数组中,其实本质实现还是利用的本地方法
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;
}
//按照下标进行添加,涉及到下标的先检查下标是否越界,检测容量,移动元素,添加元素
public void add(int index, E element) {
rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
//判断下标是否越界
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
//添加集合中所有元素进入ArrayList,先检查容量,在复制,修改元素个数
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
//从特定下标开始,将集合中的元素加入到ArrayList里面
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index); Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved); System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
//删除指定下标的元素
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;
}
//按照对象的内容删除,空和非空两种情况
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;
}
//将特定的下标的元素设置为指定的元素
public E set(int index, E element) {
rangeCheck(index); E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
//是否包含特定的元素
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
//返回特定对象第一次出现的下标,空或非空
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
//特定对象最后一次出现的下标
public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
//返回包含ArrayList元素的数组
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
//返回一条特定的子ArrayList,SubList在其中是以内部类的形式存在
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}
ArrayList源码阅读----JDK1.8的更多相关文章
- java8 ArrayList源码阅读
转载自 java8 ArrayList源码阅读 本文基于jdk1.8 JavaCollection库中有三类:List,Queue,Set 其中List,有三个子实现类:ArrayList,Vecto ...
- ArrayList源码分析--jdk1.8
ArrayList概述 1. ArrayList是可以动态扩容和动态删除冗余容量的索引序列,基于数组实现的集合. 2. ArrayList支持随机访问.克隆.序列化,元素有序且可以重复. 3. ...
- Java基础 ArrayList源码分析 JDK1.8
一.概述 本篇文章记录通过阅读JDK1.8 ArrayList源码,结合自身理解分析其实现原理. ArrayList容器类的使用频率十分频繁,它具有以下特性: 其本质是一个数组,因此它是有序集合 通过 ...
- ArrayList源码学习----JDK1.7
什么是ArrayList? ArrayList是存储一组数据的集合,底层也是基于数组的方式实现,实际上也是对数组元素的增删改查:它的主要特点是: 有序:(基于数组实现) 随机访问速度快:(进行随机访问 ...
- ArrayList源码阅读笔记(1.8)
目录 ArrayList类的注解阅读 ArrayList类的定义 属性的定义 ArrayList构造器 核心方法 普通方法 迭代器(iterator&ListIterator)实现 最后声明 ...
- ArrayList源码阅读
前言 数组是我们最常用最简单的数据结构,Java里对数组做了一个简单的包装,就是ArrayList,提供自动扩容的功能. 最常用法 list在我们日常代码中最为常用的做法是创建一个list,放入数据, ...
- Java集合-ArrayList源码解析-JDK1.8
◆ ArrayList简介 ◆ ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAcc ...
- 死磕Java之聊聊ArrayList源码(基于JDK1.8)
工作快一年了,近期打算研究一下JDK的源码,也就因此有了死磕java系列 ArrayList 是一个数组队列,相当于动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractLis ...
- ArrayList源码阅读(小白的java进阶)
ArrayList(线程不安全) ArrayList是一个其容量能够动态增长的动态数组 继承关系 构造方法 是符合collection父接口的规范的 //传0则设置为默认容量 public Array ...
随机推荐
- XML-RPC笔记
1.什么是XML-RPC RPC(Remote Procedure Call)就是相当于提供了一种"远程接口"来供外部系统调用,常用于不同平台.不同架构的系统之间互相调用. XML ...
- Ubuntu 下 CodeBlocks 修改用户自定义颜色主题 及 更新CodeBlocks到最新版本
Code::Blocks默认的白色编辑器界面看久了眼睛很累, 所以想换成dark的主题, 眼睛会舒服些. 1. 安装好codeblocks后, 先运行一次, 关闭, 这时程序会提示你是否要保存defa ...
- PHP对象5: define / const /static
define定义全局常量: define('PATH', '/data/home/www'); const也是定义常量, 一般用于类中, 饰成员属性,不可以修饰方法,如下: class Test{ c ...
- JavaScript实现水平进度条拖拽效果
<html> <head> <meta charset="UTF-8"> <title>Document</title> ...
- Why does OpenCV use BGR color format ?【转】
转自:http://www.learnopencv.com/why-does-opencv-use-bgr-color-format/ One of the elements of good desi ...
- Git和Github简单教程【转】
转自:https://www.cnblogs.com/schaepher/p/5561193.html#clone 原文链接:Git和Github简单教程 网络上关于Git和GitHub的教程不少,但 ...
- Linux运维常用的几个命令介绍【转】
Linux运维常用的几个命令介绍 1. 查看系统内核版本 [root@funsion geekxa]# cat /etc/issue CentOS release 6.5 (Final) Kerne ...
- WPF之模拟打开或关闭Windows功能
用WPF模拟打开或关闭Windows功能的实现方法其实很简单,主要用递归判断当前节点的子节点和父节点的选中状态就行了. 一.效果演示 先看看效果图: 二.部分代码 xaml代码: <TreeVi ...
- chm转换为html文件
在Windows下chm转换为html的超简单方法(反编译CHM文件的方法) 通过调用Windows命令,将chm 文件转换为html 文件. 方法: 命令行(cmd),输入hh -decompile ...
- javaScript如何跳出多重循环break、continue
先来说说break和continue之间的区别 for(var i=0;i<10;i++){ if(i>5){ break; }}console.log(i); ---6 •当i ...