通过查看ArrayList底层代码发现ArrayList有以下属性:
ArayList:
1、ArrayList如果初始化的时候没有指定容量则默认大小为10,如果容量不够则按照“newCapacity=oldCapaCity+(oldCapaCity >> 1)”算法进行扩容(原容量的1.5倍进行扩容);
2、ArrayList线程不安全,若要实现线程安全可以使用synchronized关键字或Collections.synchronizedList()方法初始化,如下
List list = Collections.synchronizedList(new ArrayList<>()); 或者使用:
3、ArrayList底层的数据结构是Object;类型的数组(Object[] elementData)所以它的很多方法都是按照数组的处理 方式进行的。
4、transient关键字修饰的变量表示不被序列化。
其中会使用到JDK中的System.arraycopy()方法,该方法可以把一个数组src复制成另外一个数组dest,是一个Native方法所以我们只关注传入参数的意义即可,源码如下:
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
各个参数的含义:
1、Object src:原数组,就是我们需要复制的数组
2、int srcPos:表示从原数组的第几个下标开始
3、Object dest:表示复制完之后的数组(可以理解为一个新的数组,但是并不是新建一个数组)
4、int destPos:表示复制之后的数据从新数组的第几个下标开始存放
5、int length:表示从原数组中复制的长度。
示例如下:
public static void main(String[] args) {
Object[] datas = new Object[20];
datas[0] = "000";
datas[1] = "111";
datas[2] = "222";
datas[3] = "333";
datas[4] = "444";
datas[5] = "555";
datas[6] = "666";
datas[7] = "777";
datas[8] = "888";
datas[9] = "999";
// 从datas中的第2个数据开始复制,复制长度为8,然后从第三个下标开始存放在新数组datas中
System.arraycopy(datas,2,datas,3,8);
for (int i = 0; i < datas.length; i++) {
System.out.print(datas[i]+" ");
}
}
执行结果:
000 111 222 222 333 444 555 666 777 888 999 null null null null null null null null null
通过以上属性我们可以自己手动实现一个简单的ArrayList,代码如下:
public class MyArrayList {
private Object[] elementData;
private int size;
private int defaultCapacity = 10;
public int size() {
return size;
}
public MyArrayList(){
this(10);
}
public MyArrayList(int initCapacity) {
if(initCapacity == 0){
this.elementData = new Object[defaultCapacity];
}else if (initCapacity > 0){
this.elementData = new Object[initCapacity];
}else{
throw new IllegalArgumentException("初始化容量参数有误");
}
}
// 获取某个节点的数据
public Object get(int index){
if(index < 0 || index > size){
throw new IndexOutOfBoundsException();
}
return elementData[index];
}
// 往数组中添加元素
public void add(Object object) {
ensureCapacity(size +1);
elementData[size] = object;
size++;
}
// 数组扩容
public void ensureCapacity(int size){
int currentCapacity = elementData.length;
if (size > currentCapacity) {
int newCapacity = currentCapacity << 1 + currentCapacity;
Object[] newElementData = new Object[newCapacity];
System.arraycopy(elementData,0,newElementData,0,currentCapacity);
elementData = newElementData;
}
}
// 往指定位置添加元素
public void add(int index, Object data){
if(index < 0 || index > size){
throw new IndexOutOfBoundsException();
}
ensureCapacity(size+1); // 扩容
System.arraycopy(elementData,index,elementData,index+1,size-index);
elementData[index] = data;
size++;
}
// 修改指定位置的数据
public Object set(int index,Object data){
if(index < 0 || index > size){
throw new IndexOutOfBoundsException();
}
Object oldData = elementData[index];
elementData[index] = data;
return oldData;
}
// 删除指定位置上的元素
public Object delete(int index){
if(index < 0 || index > size){
throw new IndexOutOfBoundsException();
}
Object oldData = elementData[index];
if(index == size) {
elementData[index] = null;
}else{
int copyLength = size-index-1;
System.arraycopy(elementData,index+1,elementData,index,copyLength);
}
size --;
return oldData;
}
}
测试类:
class MyTest{
public static void main(String[] args) {
MyArrayList myArrayList = new MyArrayList();
for (int i = 0; i < 20; i++) {
myArrayList.add(i+"aaaa");
}
MyTest.showData(myArrayList);
System.out.println("指定位置添加数据--------------------------");
myArrayList.add(3,"sdssd");
MyTest.showData(myArrayList);
System.out.println("修改指定位置的数据--------------------------");
System.out.println(myArrayList.set(5,"测试"));
MyTest.showData(myArrayList);
System.out.println("删除指定位置的数据--------------------------");
System.out.println(myArrayList.delete(2));
MyTest.showData(myArrayList);
}
private static void showData(MyArrayList myArrayList){
for (int i = 0; i < myArrayList.size(); i++) {
System.out.print(myArrayList.get(i) +" ");
}
System.out.println("");
}
}
执行结果:
0aaaa 1aaaa 2aaaa 3aaaa 4aaaa 5aaaa 6aaaa 7aaaa 8aaaa 9aaaa 10aaaa 11aaaa 12aaaa 13aaaa 14aaaa 15aaaa 16aaaa 17aaaa 18aaaa 19aaaa
指定位置添加数据--------------------------
0aaaa 1aaaa 2aaaa sdssd 3aaaa 4aaaa 5aaaa 6aaaa 7aaaa 8aaaa 9aaaa 10aaaa 11aaaa 12aaaa 13aaaa 14aaaa 15aaaa 16aaaa 17aaaa 18aaaa 19aaaa
修改指定位置的数据--------------------------
4aaaa
0aaaa 1aaaa 2aaaa sdssd 3aaaa 测试 5aaaa 6aaaa 7aaaa 8aaaa 9aaaa 10aaaa 11aaaa 12aaaa 13aaaa 14aaaa 15aaaa 16aaaa 17aaaa 18aaaa 19aaaa
删除指定位置的数据--------------------------
2aaaa
0aaaa 1aaaa sdssd 3aaaa 测试 5aaaa 6aaaa 7aaaa 8aaaa 9aaaa 10aaaa 11aaaa 12aaaa 13aaaa 14aaaa 15aaaa 16aaaa 17aaaa 18aaaa 19aaaa