閒來無事決定模仿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基礎的理解,希望能與大家一起分享