闲来无事决定模仿jdk实现ArrayList
简述:MyArrayList完全模仿jdk里面的ArrayList,但是没有继承AbstractList,实现了元素的增加、定点增加、删除、定点删除等方法,迭代器还未实现.自己实现的方法自然比不上大神的,但是目的是一样的。
ArrayList的家谱图,里面的方法也显示了,使用idea生成的
1.代码
/**
*RandomAccess 支持随机访问,毕竟ArrayList是封装数组,该接口表明遍历ArrayList采用for循环比迭代器更快
*Cloneable 克隆接口
*Serializable 序列化接口
*
*/
public class MyArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
private static final long serialVersionUID = 8683452581122892189L;
/**
* 默认大小,抄袭ArrayList
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 数组元素
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* 数组大小
*/
private int size;
/**
* 无参构造,默认大小为10,还准备了
*/
public MyArrayList(){
this(DEFAULT_CAPACITY);
}
/**
* 有参构造
* @param initialCapacity 默认10
*/
public MyArrayList(int initialCapacity) {
if(initialCapacity<0) {
try {
throw new Exception();
}catch(Exception e){
e.printStackTrace();
}
}
this.elementData=new Object[DEFAULT_CAPACITY];//
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size==0;
}
@Override
public boolean contains(Object o) {
return indexOf(o)>0?true:false;
}
@Override
public Iterator<E> iterator() {
return null;
}
@Override
public Object[] toArray() {
Object[] objects = new Object[size];
for (int i = 0; i < objects.length; i++) {
objects[i] = elementData[i];
}
return objects;
}
@Override
public <T> T[] toArray(T[] a) {
for (int i = 0; i < a.length; i++) {
a[i] = (T)elementData[i];
}
return a;
}
@Override
public boolean remove(Object o) {
int i = indexOf(o);
if(i>0){
remove(i);
return true;
}
return false;
}
@Override
public void clear() {
MyArrayList<E> myArrayList = new MyArrayList<>(size);
size=0;
}
@Override
public boolean add(E e) {
//1.数组是否装满
if(size>=elementData.length){
//扩容,采用arraycopy方法
Object[] objects = new Object[elementData.length * 2];
System.arraycopy(elementData,0,objects,0,size);
elementData = objects;
}
elementData[size]=e;
size = size+1;
return true;
}
/**
* 在指定位置添加元素,后面的向后移动
* @param index
* @param element
*/
@Override
public void add(int index, E element) {
ArrayUtils.checkIndex(index,size);
Object[] objects;
//判断是否需要扩容
if(size>=elementData.length){
objects = new Object[elementData.length * 2];
}else{
objects = new Object[elementData.length];
}
size++;
System.arraycopy(elementData,0,objects,0,index);
objects[index] = element;
for (int i = index; i < size; i++) {
objects[i+1] = elementData[i];
}
elementData = objects;
}
/**
* 删除指定位置元素,将后面的数组往前移动
* @param index
* @return
*/
@Override
public E remove(int index) {
ArrayUtils.checkIndex(index,size);
E e = (E)elementData[index];
int nextLength = elementData.length;
Object[] objects = new Object[nextLength];
System.arraycopy(elementData,0,objects,0,elementData.length);
for (int i = index+1; i < nextLength; i++) {
objects[i-1] = elementData[i];
}
elementData = objects;
size--;
return e;
}
@Override
public int indexOf(Object o) {
if(o==null)return -1;
for (int i = 0; i <elementData.length ; i++) {
if(o.equals(elementData[i]))return i;
}
return -1;
}
@Override
public int lastIndexOf(Object o) {
if(o==null)return -1;
for (int i = elementData.length-1; i <elementData.length ; i++) {
if(o.equals(elementData[i]))return i;
}
return -1;
}
@Override
public boolean containsAll(Collection<?> c) {
return false;
}
@Override
public boolean addAll(Collection<? extends E> c) {
return false;
}
@Override
public boolean addAll(int index, Collection<? extends E> c) {
return false;
}
@Override
public boolean removeAll(Collection<?> c) {
return false;
}
@Override
public boolean retainAll(Collection<?> c) {
return false;
}
@Override
public ListIterator<E> listIterator() {
return null;
}
@Override
public ListIterator<E> listIterator(int index) {
return null;
}
@Override
public List<E> subList(int fromIndex, int toIndex) {
return null;
}
@Override
public E get(int index) {
ArrayUtils.checkIndex(index,size);
return (E)elementData[index];
}
@Override
public E set(int index, E element) {
return null;
}
}
public class ArrayUtils {
/**
* 数组下标越界检查
* @param index 数组下标
* @param size 数组大小
* @param <X> 运行时异常
* @return
*/
public static <X extends RuntimeException> int checkIndex(int index,int size){
if(index<0||index>size-1)throw new RuntimeException("数组下标越界");
return index;
}
}
2.代码思路
MyArrayList模仿ArrayList,毕竟List试衣镜定义好的接口,实现里面方法即可。
ArrayUtils 模仿ArrayList里面使用的工具类,判断数组下表越界。
目前实现的方法思路都有,可能还有错误或者实现思路效率低下等问题
3.测试
1.add方法和get方法
@Test
public void test3(){
MyArrayList<String> list = new MyArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("ads");
list.add("asdf");
list.add("asdf");
list.add("gras");
list.add("asfd");
list.add("asdf");
list.add("asfd");
list.add("asfasdf");
list.add("ads");
System.out.println(list.size());
Assert.assertSame("张三",list.get(0));
Assert.assertSame("李四",list.get(1));
Assert.assertSame("王五",list.get(2));
Assert.assertEquals("溜溜",list.get(3));
Assert.assertEquals("七七",list.get(4));
Assert.assertEquals("八八",list.get(5));
Assert.assertEquals("九九",list.get(6));
Assert.assertEquals("试试",list.get(7));
Assert.assertEquals("事宜",list.get(8));
Assert.assertEquals("十二",list.get(9));
Assert.assertEquals("十三",list.get(10));
Assert.assertEquals("十四",list.get(11));
list.stream().forEach(System.out::print);
//结果
//12
//张三李四王五溜溜七七八八九九试试事宜十二十三十四
}
2.remove方法
@Test
public void test3(){
MyArrayList<String> list = new MyArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("ads");
list.add("asdf");
list.add("asdf");
list.add("gras");
list.add("asfd");
list.add("asdf");
list.add("asfd");
list.add("asfasdf");
list.add("ads");
System.out.println(list.size());
list.stream().forEach(System.out::print);
System.out.println(list.indexOf("李四"));
list.remove(1);
System.out.println(list.indexOf("李四"));
System.out.println(list.size());
list.stream().forEach(System.out::print);
//结果
//12
//张三李四王五溜溜七七八八九九试试事宜十二十三十四1
//-1
//11
//张三王五溜溜七七八八九九试试事宜十二十三十四
}
2.add(int i,E e)方法
@Test
public void test3(){
MyArrayList<String> list = new MyArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("ads");
list.add("asdf");
list.add("asdf");
list.add("gras");
list.add("asfd");
list.add("asdf");
list.add("asfd");
list.add("asfasdf");
list.add("ads");
System.out.println(list.size());
list.stream().forEach(System.out::print);
list.add(2,"十八");
System.out.println(list.size());
list.stream().forEach(System.out::print);
//结果
//12
//张三李四王五溜溜七七八八九九试试事宜十二十三十四13
//张三李四十八王五溜溜七七八八九九试试事宜十二十三十四
}
目前实现的方法就这么多,下个版本实现迭代器。进行遍历等
4.结束
写这个只是为了加深对java基础的理解,希望能与大家一起分享