数组实现
父类:AbstractList
接口:List,RandomAccess,Cloneable,Serializable
字段:
//默认容量
private static final int DEFAULT_CAPACITY = 10;
//空的数组,构造函数参数为0和trim中使用,构造参数给0的人绝对会被打死,每放一个元素,就要重新copy一次
private static final Object[] EMPTY_ELEMENTDATA = {}; //实际保存数组,transient,这个字段不用写入流
transient Object[] elementData
//实际元素数目
private int size;
 public ArrayList(int initialCapacity)
{
if (initialCapacity > 0)
{
this.elementData = new Object[initialCapacity];
}
else if (initialCapacity == 0)
{
//注意初始容量为0时给的对象,EMPTY_ELEMENTDATA
this.elementData = EMPTY_ELEMENTDATA;
}
else
{
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
} public ArrayList()
{
//默认构造函数
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
} public ArrayList(Collection<? extends E> c)
{
//转入的集合转换为数组
elementData = c.toArray();
//改变自己的size
if ((size = elementData.length) != 0)
{
//这里有个坑,可能不能正确的返回Object[] Class对象,不能的话复制
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else
{
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
} //截断,在原数组上移动
public void trimToSize()
{
modCount++;
if (size < elementData.length)
{
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
} //比较关心的几个方法,存放,取出,查找
//查找,运行时间上界O(n),从这里也可用看出是允许放null
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;
}
//返回index位置的元素
E elementData(int index)
{
return (E) elementData[index];
} //获取对应位置元素,O(1)
public E get(int index)
{
//检查size,并没有判断小于0
rangeCheck(index);
return elementData(index);
} //将元素放在对应位置,index<size,list当成数组使用,注意,这样的代码会报错
//List<String> list = new ArrayList<>(100);
// list.set(10, "123");
//根据构造函数可以知道,已经开辟了100长度的数组,但是就是不让你用
public E set(int index, E element)
{
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
} private void grow(int minCapacity)
{
// overflow-conscious code
int oldCapacity = elementData.length;
//原来的1.5备长度
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
elementData = Arrays.copyOf(elementData, newCapacity);
} private void ensureExplicitCapacity(int minCapacity)
{
modCount++; // overflow-conscious code
//1-0,进入if,进行内存复制,开辟新的数组
if (minCapacity - elementData.length > 0)
grow(minCapacity);
} private void ensureCapacityInternal(int minCapacity)
{
//构造函数给0,这里是false
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
{
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
} //ensureExplicitCapacity(1);
ensureExplicitCapacity(minCapacity);
} //增加一个元素
public boolean add(E e)
{
//为什么构造函数给0会被打死,看下面这个函数,一来就要新数组,新的数组长度也只有1
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
} //元素放到index位置,0<=index<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++;
}
//移除
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;
}
//O(n)的移除,注意在fastRemove方法里面也会出现内存复制
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;
} //为什么elementData不用置null,方便重用
public void clear()
{
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
} //浅克隆
public Object clone()
{
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
} //返回副本
public Object[] toArray()
{
return Arrays.copyOf(elementData, size);
} 结尾附上一个内存分布的代码,有指针真好
int main(int argc, char* argv[])
{
//int ba[4];
int a[] = { 1, 2, 3, 4 };
int c = 5;
int d = 6;
int dd = 7;
cout << a << endl;
cout << a[-1] << endl;
cout << a-1 << endl;
cout<<&dd<<endl;
cout << &d << endl;
cout << &c << endl;
//memcpy(ba, a, sizeof(int) * 4);
//cout << ba[0] << endl;
//cout << ba[1] << endl;
return 0;
}

  

ArrayList实现的更多相关文章

  1. 计算机程序的思维逻辑 (38) - 剖析ArrayList

    从本节开始,我们探讨Java中的容器类,所谓容器,顾名思义就是容纳其他数据的,计算机课程中有一门课叫数据结构,可以粗略对应于Java中的容器类,我们不会介绍所有数据结构的内容,但会介绍Java中的主要 ...

  2. 分享个 之前写好的 android 文件流缓存类,专门处理 ArrayList、bean。

    转载麻烦声明出处:http://www.cnblogs.com/linguanh/ 目录: 1,前序 2,作用 3,特点 4,代码 1,前序  在开发过程中,client 和 server 数据交流一 ...

  3. 深入理解java中的ArrayList和LinkedList

    杂谈最基本数据结构--"线性表": 表结构是一种最基本的数据结构,最常见的实现是数组,几乎在每个程序每一种开发语言中都提供了数组这个顺序存储的线性表结构实现. 什么是线性表? 由0 ...

  4. 【干货】用大白话聊聊JavaSE — ArrayList 深入剖析和Java基础知识详解(二)

    在上一节中,我们简单阐述了Java的一些基础知识,比如多态,接口的实现等. 然后,演示了ArrayList的几个基本方法. ArrayList是一个集合框架,它的底层其实就是一个数组,这一点,官方文档 ...

  5. WebAPI接口返回ArrayList包含Dictionary对象正确解析

    一.问题提出 为了减少流量,将key-value(键值对)直接输出到Dictionary<string, string>,接口返回结果如下: 其中{}里面内容如下: 上图显示600是键,4 ...

  6. ArrayList LinkedList源码解析

    在java中,集合这一数据结构应用广泛,应用最多的莫过于List接口下面的ArrayList和LinkedList; 我们先说List, public interface List<E> ...

  7. ArrayList、Vector、LinkedList的区别联系?

    1.ArrayList.Vector.LinkedList类都是java.util包中,均为可伸缩数组. 2.ArrayList和Vector底层都是数组实现的,所以,索引数据快,删除.插入数据慢. ...

  8. ArrayList、Vector、HashMap、HashSet的默认初始容量、加载因子、扩容增量

    当底层实现涉及到扩容时,容器或重新分配一段更大的连续内存(如果是离散分配则不需要重新分配,离散分配都是插入新元素时动态分配内存),要将容器原来的数据全部复制到新的内存上,这无疑使效率大大降低. 加载因 ...

  9. Java中Vector和ArrayList的区别

    首先看这两类都实现List接口,而List接口一共有三个实现类,分别是ArrayList.Vector和LinkedList.List用于存放多个元素,能够维护元素的次序,并且允许元素的重复.3个具体 ...

  10. C#语言基础——集合(ArrayList集合)

    集合及特殊集合 集合的基本信息: System.Collections 命名空间包含接口和类,这些接口和类定义各种对象(如列表.队列.位数组.哈希表和字典)的集合.System.Collections ...

随机推荐

  1. 查找一个Class到底在那一个jar文件里

    整理自己的一些笔记,发觉这个命令 ,看起来是用来找一个Class到底在那一个jar文件里的. 虽然没有再测一下,估计是好使的. 先在博客园里记下来,防止自己忘掉. findstr /S /M org. ...

  2. idea JMX 连接器服务器通信错误

    错误描述:错误: JMX 连接器服务器通信错误: service:jmx:rmi://DESKTOP-46OA4KK 打开Edit Configurations 发现vm options那一栏居然是空 ...

  3. echarta3 北京,上海地图

    1.首先你得到echarts官网下载js,建议下载完整代码,这样你就很容易根据我的路径找到beijing.js 2.把echarts.js和beijingi.js根据你的路径引对,然后就可以copy我 ...

  4. java 替换字符串中的中括号

    正确方式:"[adbdesf]".replaceAll("\\[", "").replaceAll("\\]", &qu ...

  5. 古董留念 - Microsoft Office 4.2中文版

    Office 4.2是Office 95的前一个版本,最适合运行在Windows 3.x上,但即使是最新的Windows 7 32位版也是可以安装它的(不信你可以试试)! 原版以软盘为载体,安装一次需 ...

  6. Alpha冲刺一 (10/10)

    前言 队名:拖鞋旅游队 组长博客:https://www.cnblogs.com/Sulumer/p/10034872.html 作业博客:https://edu.cnblogs.com/campus ...

  7. 用pil产生验证码出现:ImportError: The _imagingft C module is not installed

    这个是由于PIL没有编译freetype导致的查看 lib/python2.7/site-packages/PIL/看看 _imagingft.so 是否存在 # 需要先安装jpeg库wget htt ...

  8. Buildroot make网卡interfaces文件被修改

    /******************************************************************************** * Buildroot make网卡 ...

  9. SQL Server2008 R2开启远程连接总结

    ============================== SQL Server2008 R2开启远程连接(最全总结) ============================== 安装过程:适用W ...

  10. SpookyOTP

    https://pypi.python.org/pypi/SpookyOTP/1.1.1 SpookyOTP 1.1.1 Downloads ↓ A lightweight Python 2/3 pa ...