- 一、ArrayList的构造
- 二、ArrayList常见操作
- 三、模拟实现
- 1.创建类及其构造方法
- 2.指定顺序表初始容量
- 3.判断列表是否为空
- 4.尾插
- 5.将e插入到index位置
- 6.删除index位置上元素
- 7.删除遇到的第一个o
- 8.获取index位置上元素
- 9.将index位置上的元素设置为e
- 10.清空
- 11.判断o是否在线性表中
- 12.截取部分list
- 13.重写toString
- 14.主方法
- 四、输出结果
public class MyArrayList1{ private Object[] array; private int size; //构造方法:无参构造 public MyArrayList1(){ } public int size(){ return size; } }
由于列表中存放元素各种类型都有可能,这里采用泛型
public MyArrayList1(int initCapacity){
if(initCapacity>=0){
array=new Object[initCapacity];
}else{
throw new IllegalArgumentException("初始容量为负数");
}
}
初始容量必须为正整数,否则抛异常。
3.判断列表是否为空public boolean isEmpty(){
return size==0;
}
4.尾插
public boolean add(E e){
ensureCapacity(size+1);
array[size++]=e;
return true;
}
//扩容
private static final int MAX_ARRAY_SIZE=Integer.MAX_VALUE-8;
private void ensureCapacity(int initCapacity){
int oldCapacity= array.length;
//初步预计按照1.5倍大小扩容
int newCapacity=oldCapacity+(oldCapacity>>1);
//如果扩容后小于初始容量,则仍然按照初始容量
if(newCapacityMAX_ARRAY_SIZE){
newCapacity=MAX_ARRAY_SIZE;
}
array= Arrays.copyOf(array,newCapacity);
}
步骤:
1.扩容
2.将元素放在size的位置
3.将size+1
细化扩容:
1.首先设置列表的最大值:
数组对象的形状和结构(如int值数组)与标准Java对象类似。主要区别在于数组对象有一个额外的元数据,用于表示数组的大小。所以这里的最大值是整型最大值-8.
2.初步预计按照1.5倍大小扩容,如果扩容后小于初始容量,则仍然按照初始容量;如果扩容后超过最大容量,则按照最大容量。
3.使用copyOf进行扩容
public void add(int index,E e){
rangeCheckForAdd(index);
ensureCapacity(size+1);
//将index及其之后的元素统一往后搬移一个位置
for(int i=size-1;i>=index;i--){
array[i+1]=array[i];
}
array[index]=e;
size++;
}
//检测插入时下标是否异常
private void rangeCheckForAdd(int index){
if(index>size){
throw new IllegalArgumentException("add下标越界");
}
}
步骤:
1.检测插入时下标是否异常,是的话抛出异常
2.扩容
3.将index及其之后的元素统一往后搬移一个位置(这里一定要注意从后往前搬,如果从前往后搬会出现搬移的所有元素都是同一个元素的现象)
public E remove(int index){
rangeCheck(index);
E e=(E)array[index];
//将index之后的元素统一往前搬移一个位置
for(int i=index+1;i=size){
throw new IndexOutOfBoundsException("下标越界");
}
}
步骤:
1.检测下标是否异常,是的话抛出异常
2.将下标为index的元素强转为E类型,方便后续返回
3.将index之后的元素统一往前搬移一个位置(从前往后)
public boolean remove(Object o){
int index=indexOf(o);
if(index==-1){
return false;
}
remove(index);
return true;
}
//获取o第一次出现的位置
private int indexOf(Object o){
if(o==null){
for(int i=0;i
步骤:
1.获取o第一次出现的位置,将null单独处置,如果没有o返回-1,返回false
2.有的话调用remove().返回true
8.获取index位置上元素
public E get(int index){
rangeCheck(index);
E e=(E)array[index];
return e;
}
步骤:
1.检测下标是否异常
2.将下标index位置元素强转为E类型并返回
9.将index位置上的元素设置为e
public E set(int index,E e){
rangeCheck(index);
array[index]=e;
return e;
}
步骤:
1.检测下标是否异常
2.将index位置元素设置为e
3.返回e
10.清空
public void clear(){
for(int i=0;i
将每个元素设置为null,size=0.
11.判断o是否在线性表中
public boolean contains(Object o){
return indexOf(o)>0;
}
其实就是判断o所在下标是否大于o,因为当时indexOf()不在时返回-1.
12.截取部分list
MyArrayList1 subList(int fromIndex,int toIndex){
if(toIndex-fromIndex<0){
throw new IllegalArgumentException("参数非法");
}
MyArrayList1 list=new MyArrayList1<>(toIndex-fromIndex);
for(int i=fromIndex;i
步骤:
1.判断fromIndex和toIndex参数合法性
2.创建一个新列表用来保存截取后的列表
13.重写toString
@Override
public String toString(){
String s="[";
if(size>0){
for(int i=0;i
14.主方法
public static void main(String[] args) {
MyArrayList1 list=new MyArrayList1<>(3);
list.add(1);
list.add(2);
list.add(3);
list.add(4);
System.out.println(list);
System.out.println("长度为:"+list.size());
list.add(0,0);
System.out.println(list);
if(list.contains(5)){
list.add(5);
}
list.add(0);
System.out.println(list);
System.out.println(list.indexOf(0));
System.out.println(list.lastIndexOf(0));
list.remove(0);
System.out.println(list);
list.clear();
System.out.println(list);
}
}
四、输出结果



