咱們知道 ArrayList 是一個集合,它能存放各類不一樣類型的數據,並且其容量是自動增加的。那麼它是怎麼實現的呢?java
其實 ArrayList 的底層是用 數組實現的。咱們查看 JDK 源碼也能夠發現。而用數組實現集合的原理有兩點:數組
一、能自動擴容函數
二、能存放不一樣類型的數據this
這兩點咱們是這樣解決的:對象
一、當一個數據存放滿了,咱們就將這個數據複製到一個新的數組中,而這個新的數組容量要比原數組大。經過這樣不斷的擴大數組長度,也就是集合的容量。那麼這裏咱們用到了這個方法 System.arraycopyblog
完整的寫法爲:public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)索引
參數ci
@ src -- 這是源數組 @ srcPos -- 這是源數組中的起始位置 @dest -- 這是目標數組 @ destPos -- 這是目標數據中的起始位置 @ length -- 這是一個要複製的數組元素的數目rem
int arr1[] = {0,1,2,3,4,5}; int arr2[] = {0,10,20,30,40,50}; System.arraycopy(arr1,0,arr2,1,2); //結果爲:arr2 = [0,0,1,30,40,50];
二、第二個問題,咱們只須要聲明爲 Object 類型的數組就能夠了。get
完整代碼以下:
package com.ys.collection; public class MyArrayList { //用於存儲數據 private transient Object[] data = null; //集合的元素個數 private int size = 0; //定義一個常量爲 10.(後面用於定義默認的集合大小) private static final int DEFAULT_CAPACITY = 10; /*** * 有參構造函數 * 指定數組的大小 * @param length */ public MyArrayList(int initialCapacity){ if(initialCapacity < 0){ throw new IllegalArgumentException("非法的集合初始容量值 Illegal Capacity: "+ initialCapacity); }else{ //實例化數組 this.data = new Object[initialCapacity]; } } /*** * 無參構造函數 * 指定數組的初始大小爲 10 */ public MyArrayList(){ this(DEFAULT_CAPACITY); } /*** * 一、複製原數組,並擴容一倍 * 二、複製原數組,並擴容一倍,並在指定位置插入對象 * @param index * @param obj */ public void checkIncrease(int index,Object obj){ if(size >= data.length){ //實例化一個新數組 Object[] newData = new Object[size*2]; if(index == -1 && obj == null){ System.arraycopy(data, 0, newData, 0, size); }else{ //將要插入索引位置前面的對象 拷貝 System.arraycopy(data, index, newData, index+1, size-index); } //將 newData 數組賦值給 data數組 data = newData; newData = null; } } /*** * 獲取數組的大小 * @return */ public int getSize(){ return this.size; } /*** * 根據元素得到在集合中的索引 * @param o * @return */ public int indexOf(Object o) { if (o == null) { for (int i = 0; i < data.length; i++) if (data[i]==null) return i; } else { for (int i = 0; i < data.length; i++) if (o.equals(data[i])) return i; } return -1; } /*** * 在尾部添加元素 * @param obj * @return */ public boolean add(Object obj){ //檢查是否須要擴容 checkIncrease(-1, null); data[size++] = obj; return true; } /** * 判斷給定索引是否越界 * @param index * @return */ public boolean checkIndexOut(int index){ if(index > size || index < 0){ throw new IndexOutOfBoundsException("指定的索引越界,集合大小爲:"+size+",您指定的索引大小爲:"+index); } return true; } public boolean add(int index,Object obj){ //若是給定索引長度恰好等於原數組長度,那麼直接在尾部添加進去 if(index == size){ add(obj); } //checkIndexOut()若是不拋異常,默認 index <=size,且 index > 0 else if(checkIndexOut(index)){ if(size < data.length){ System.arraycopy(data, index, data, index+1, size-index); data[index] = obj; }else{ //須要擴容 checkIncrease(index, obj); } size++; } return true; } /*** * 根據索引得到元素 * @param index * @return */ public Object get(int index){ checkIndexOut(index); return data[index]; } /*** * 刪除全部元素 */ public void removeAll(){ for(int i = 0 ; i < data.length ; i++){ data[i] = null; } } /*** * 根據索引刪除元素 * @param index * @return */ public Object remove(int index){ if(index == size+1){ throw new IndexOutOfBoundsException("指定的索引越界,集合大小爲:"+size+",您指定的索引大小爲:"+index); }else if(checkIndexOut(index)){ //保存對象 Object obj = data[index]; if(index == size){ data[index] = null; }else{ //將後邊的數組向前移動一位 System.arraycopy(data, index+1, data, index, size-index); } size--; return obj; } return null; } /*** * 刪除指定的元素,刪除成功返回 true,失敗返回 false * @param obj * @return */ public boolean remove(Object obj){ for(int i = 0 ; i < size ; i++){ if(obj.equals(data[i])){ remove(i); return true; } } return false; } /*** * 在指定位置修改元素,經過索引,修改完成後返回原數據 * @param index * @param obj * @return */ public Object change(int index,Object obj){ checkIndexOut(index); Object oldObj = data[index]; data[index] = obj; return oldObj; } /*** * 查看集合中是否包含某個元素,若是有,返回 true,沒有返回 false * @param obj * @return */ public boolean contain(Object obj){ for(int i = 0 ; i < data.length ; i++){ if(obj.equals(data[i])){ return true; } } return false; } public static void main(String [] args){ MyArrayList my = new MyArrayList(); //System.out.println(my.data.length); my.add(0,3); //System.out.println(my.getSize()); my.add(0,4); //System.out.println(my.getSize()); my.add(0,5); //my.removeAll(); //my.remove(2); //System.out.println(my.get(2)); System.out.println(my.indexOf(null)); System.out.println(my.contain(2)); for(int i = 0 ; i < my.data.length ; i++){ System.out.println(my.data[i]); } } }