自定义简单实现ArrayList
程序员文章站
2022-03-21 17:04:50
...
ArrayList是基于数组实现的。
首先明白两个数组的方法
- System.arraycopy()方法
源码如下
src:源对象
srcPos:源数组中的起始位置
dest:目标数组对象
destPos:目标数据中的起始位置
length:要拷贝的数组元素的数量
- Arrays.copyOf()方法
数组拷贝时调用的是本地方法 System.arraycopy() ;
Arrays.copyOf()方法返回的数组是新的数组对象,原数组对象仍是原数组对象,不变,该拷贝不会影响原来的数组。
/**
*1.构造函数,如果调用无参构造,则初始值默认为10,
*2.add方法
* 2.1 先判断是否需要扩容
* 2.1.1扩容后数组的大小设置为是1.5倍
* 2.1.2需要判断扩容后的容量是否充足
* 2.1.3如果最小容量比新容量要小,则采用初始容量minCapacity
* 2.2 在进行添加
*3.get方法
* 3.1先判断是否超过实际数据长度
*4.remove方法
* 4.1数组需要移动的次数
* 4.2从后往前覆盖
* 4.3将原来实际数据的数组下标的最后一位置空
* 4.4返回删除元素
* @param <E>
*/
public class ArrayListDemo<E> {
//默认初始值
private static final int DEFAULT_CAPACITY = 10;
//保存ArrayList中的数组
private Object[] elementData;
//数据实际的数量
private int size;
public ArrayListDemo() {
//默认初始值
this(DEFAULT_CAPACITY);
}
public ArrayListDemo(int initialCapacity) {
if(initialCapacity > 0){
elementData = new Object[initialCapacity];
}
}
//添加方法
public void add(E e){
//判断是否需要扩容
isNeedExport(size+1);
elementData[size++] = e;
}
//添加方法
public void add(int index,E e){
//先判断是否超过实际数据长度
checkIndex(index);
//判断是否需要扩容
isNeedExport(size+1);
//数组需要移动的次数
int removeNum = size - index;
System.arraycopy(elementData,index,elementData,index+1,removeNum);
elementData[index] = e;
size++;
}
//获取数据
public E get(int index){
//先判断是否超过实际数据长度
checkIndex(index);
return (E) elementData[index];
}
//
public E remove(int index){
E e = get(index);
//数组需要移动的次数
int removeNum = elementData.length - index - 1;
if(removeNum > 0){
//从后往前覆盖
System.arraycopy(elementData,index+1,elementData,index,removeNum);
}
//将原来实际数据的数组下标的最后一位置空
elementData[--size] = null;
//返回删除元素
return e;
}
//检测数组下标
private void checkIndex(int index) {
if(index >= size){
throw new IndexOutOfBoundsException("数组越界啦!");
}
}
//扩容方法
private void isNeedExport(int minCapacity) {
//如果实际数量达到了数组的长度,则需要扩容
if(size == elementData.length){
//扩容前数组的大小
int oldCapacity = elementData.length;
//扩容后数组的大小,就是1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果原数组大小为1,1.5倍扩容后还是1,所以,需要判断扩容后的容量是否充足
if(oldCapacity > newCapacity){
//如果最小容量比新容量要小,则采用初始容量minCapacity
newCapacity = minCapacity;
}
elementData = Arrays.copyOf(elementData,newCapacity);
}
}
public int getSize() {
return size;
}
}
Vector
Vector是线程安全的,但是性能比ArrayList要低。
ArrayList,Vector主要区别为以下几点:
(1)Vector是线程安全的,源码中有很多的synchronized可以看出,而ArrayList不是。导致Vector效率无法和ArrayList相比
(2)ArrayList和Vector都采用线性连续存储空间,当存储空间不足的时候,ArrayList默认增加为原来的50%,Vector默认增加为原来的一倍
(3)Vector可以设置capacityIncrement,而ArrayList不可以,从字面理解就是capacity容量,Increment增加,容量增长的参数