一.引言
众所周知ArrayList是一种数组的实现方式,也就说明其有序有下标不肯重复,查询快增删慢的特点,今天有时间就研究了一下其实现方法并手写了一些,实现原理草考以下链接
实现原理
二.demo实践
1.首先创建一个NewList接口
package org.ligh.arraylist;
/**
* Created by ${ligh} on 2019/2/15 上午9:22
*/
public interface NewList<E> {
public void add(E object);
public void add(int index,E object);
public boolean remove(E object);
public Object remove(int index);
public int getSize();
public Object get(int index);
public void update(int index,Object obj);
}
2.创建一个NewArrayList实现类,开始具体写demo
package org.ligh.arraylist;
import java.util.Arrays;
/**
* Created by ${ligh} on 2019/2/15 上午9:26
*/
public class NewArrayList<E> implements NewList<E> {
//定义属性
private transient Object[] elementData;
//arrayList实际数量
private int size;
protected transient int modCount = 0;
public NewArrayList() {
this(10);
}
public NewArrayList(int initialCapacity) {
if (initialCapacity<0)
throw new IllegalArgumentException("Illegal Capacity " +initialCapacity);
elementData = new Object[initialCapacity];
}
/**
* 扩容操作
*
* @param minCapacity
*/
public void ensureExplicitCapacity(int minCapacity){
if(minCapacity == size){
//获取原来的长度
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if(newCapacity<minCapacity){
newCapacity = minCapacity;
}
//把原来的元素赋值到新的数组长度内存中
elementData = Arrays.copyOf(elementData,newCapacity);
}
}
/**
* 判断是否下标越界
*
* @param index
*/
public void rangCheck(int index){
if(index >= size){
throw new IndexOutOfBoundsException("length--->" +index);
}
}
/**
* 添加操作
*
* @param object
*/
@Override
public void add(E object) {
//判断是否需要扩容
ensureExplicitCapacity(size+1);
elementData[size++] = object;
}
@Override
public void add(int index, E object) {
//判断是否下标越界
rangCheck(index);
//判断是否需要扩容
ensureExplicitCapacity(size+1);
System.arraycopy(elementData,index,elementData,index+1,size);
elementData[index] = object;
size++;
}
/**
* 删除操作
*
* @param object
* @return
*/
@Override
public boolean remove(E object) {
for (int index=0;index<size;index++){
if(elementData[index] .equals(object)){
remove(index);
return true;
}
}
return false;
}
/**
* 根据下标删除
*
* @param index
* @return
*/
@Override
public Object remove(int index) {
rangCheck(index);
Object o = get(index);
int numMoved = elementData.length - 1 - index;
if(numMoved>0){
System.arraycopy(elementData,index+1,elementData,index,numMoved);
}
elementData[--size] = null;
return o;
}
@Override
public int getSize() {
return size;
}
@Override
public Object get(int index) {
rangCheck(index);
return elementData[index];
}
/**
* 根据下标更新数据
*
* @param index
* @param obj
*/
@Override
public void update(int index, Object obj) {
rangCheck(index);
//先删除需要更新的对象
remove(index);
E e = (E) obj;
add(index,e);
}
}
3.测试
package org.ligh.arraylist;
/**
* Created by ${ligh} on 2019/2/15 上午10:02
*/
public class TestEasyArrayList {
public static void main(String[] args) {
NewList<Object> list = new NewArrayList<>();
System.out.println("=====添加操作====");
list.add("李国辉");
list.add("沈庆华");
list.add("小猪猪");
list.add("小笨猪");
for (int i =0;i<list.getSize();i++){
System.out.println(i+"<---->"+list.get(i));
}
System.out.println("=====更新操作=====");
int size1 = list.getSize();
System.out.println("集合长度: "+size1);
list.update(2,"新年好!");
for (int i =0;i<list.getSize();i++){
System.out.println(i+"<---->"+list.get(i));
}
System.out.println("=====删除操作====");
list.remove(3);
for (int i =0;i<list.getSize();i++){
System.out.println(i+"<---->"+list.get(i));
}
System.out.println("=====查询操作====");
int size = list.getSize();
String o = list.get(2).toString();
System.out.println("数组长度:"+size+"获取的值: "+o);
}
}
至此就完成了手下ArrayList的实现,其中最需要注意的就是下标的变化,另外一定要注意集合数组的空间初始化一定要有。