自定義ArrayList(十八)

勿以惡小而爲之,勿以善小而不爲--------------------------劉備

勸諸君,多行善事積福報,莫作惡

上一章簡單介紹了 Arrays工具類的使用(十七),如果沒有看過,請觀看上一章

一. 自定義ArrayList

ArrayList 位於 java.util 包下, 內部封裝的是數組, 用於快速查詢數據, 也支持添加,移除等操作。

由於是內部封裝數組,數組複製操作很多,建議看一看上一章節的內容。

ArrayList 的源碼非常好,建議多讀一下。

老蝴蝶簡單自定義一個 ArrayList, 實現相應的基礎功能。

一.一 自定義 MyArrayList, 實現 ArrayList 功能

package com.yjl.collection;

import java.util.Arrays;

/**
 * package: com.yjl.collection
 * className: MyArrayList
 * Description: 用於實現 java.util.ArrayList 的集合功能
 *
 * @author : 兩個蝴蝶飛
 * @Date :2020/6/10 12:47
 */
public class MyArrayList <E>{
    /**
     * 默認的長度是10
     */
    private final static int DEFAULT_CAPICATY=10;
    /**
     * 用數組進行集合
     */
    private Object[] elementData;
    /**
     * 目前存儲的長度
     */
    private int size;

    /**
     * 空構造時,指定長度爲默認的長度
     */
    public MyArrayList(){
       this(DEFAULT_CAPICATY);
    }

    /**
     * 傳入長度
     * @param initCapicaty 初始化長度
     */
    public MyArrayList(int initCapicaty){

        if(initCapicaty<0){
            throw new RuntimeException("長度過小");
        }else if(initCapicaty==0){
            initCapicaty=DEFAULT_CAPICATY;
        }
        //初始化數組
        elementData=new Object[initCapicaty];
        //初始化長度
        size=0;
    }

    public MyArrayList(MyArrayList maList){
        //轉換成數組
      Object[] obj=maList.toArray();

      elementData=obj;

      size=obj.length;
    }

    /**
     *
     * @return 返回長度
     */
    public int size(){
        return size;
    }

    /**
     *
     * @return 集合爲空,返回true,不爲空,返回false
     */
    public boolean isEmpty(){
        return size==0?true:false;
    }

    /**
     *
     * @param e 添加的元素
     * @return 添加單個集合
     */
    public boolean add(E e){

        //是否需要擴容
        beforeAddLength((size+(int)(size<<2)));
        //添加到末尾
         elementData[size++]=e;

         return true;
    }

    private void beforeAddLength(int maxLength){
        //如果添加到末尾了
        if(size==elementData.length){

            //擴展寬度
            Object[] copy=new Object[maxLength];

            //複製數組
            System.arraycopy(elementData,0,copy,0,size);
            //引用變換
            elementData=copy;
        }
    }

    /**
     *
     * @param index 索引
     * @param e 添加的元素
     */
    public void add(int index,E e){

        beforeAddLength((size+(int)(size<<2)));

        System.arraycopy(elementData,index,elementData,index+1,size-index);

        //當前位置 index 元素爲 e
        elementData[index]=e;

        size++;

    }

    /**
     *
     * @param maList
     * @return 添加所有集合元素
     */
    public boolean addAll(MyArrayList maList){

        Object[] temp=maList.toArray();

        int newLength=temp.length;

        //長度大了,那麼就擴展
        if(size+newLength>elementData.length){

            beforeAddLength(size+newLength);
        }

        System.arraycopy(temp,0,elementData,size,newLength);

        size=size+newLength;

        return true;
    }

    /**
     *
     * @param index 索引
     * @param maList 集合
     *
     */
    public void addAll(int index,MyArrayList maList){

        Object[] temp=maList.toArray();

        int newLength=temp.length;

        //長度大了,那麼就擴展
        if(size+newLength>elementData.length){

            beforeAddLength(size+newLength);
        }

        if(index<size){

            //自身複製一下
            System.arraycopy(elementData,index,elementData,index+1,size-index);
        }

        System.arraycopy(temp,0,elementData,index,newLength);
        size=size+newLength;

    }

    /**
     * 清理
     */
    public void clear(){

        for(int i=0;i<elementData.length;i++){
            elementData[i]=null;
        }
        size=0;
    }

    /**
     * 克隆
     * @return
     */
    public MyArrayList clone(){


        try {
            MyArrayList<E> maList = (MyArrayList<E>) super.clone();
            maList.elementData=elementData;
            maList.size=size;

        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *
     * @param e
     * @return 是否包含某個對象
     */
    public boolean contains(Object e){
       return indexOf(e)>=0?true:false;
    }

    /**
     *
     * @param e 元素
     * @return 返回對象所在的位置,從前往後
     */
    public int indexOf(Object e){

        if(e==null){
            for(int i=0;i<size;i++){
                if(null==elementData[i]){
                    return i;
                }
            }
        }else{
            for(int i=0;i<size;i++){
                if(e.equals(elementData[i])){
                    return i;
                }
            }
        }

        return -1;
    }

    /**
     *
     * @param e
     * @return  返回對象所在的位置,從後往前
     */
    public int lastIndexOf(Object e){
        if(e==null){
            for(int i=size-1;i>=0;i--){
                if(null==elementData[i]){
                    return i;
                }
            }
        }else{
            for(int i=size-1;i>=0;i--){
                if(e.equals(elementData[i])){
                    return i;
                }
            }
        }

        return -1;
    }

    /**
     *
     * @param index
     * @param e
     * @return 設置值, 返回以前的老的值
     */
    public E set(int index,Object e){
        E old=get(index);

        elementData[index]=e;

        return old;
    }

    /**
     *
     * @param index
     * @return 獲取某個索引的值
     */
    public E get(int index){

        if(index<0){
            throw new RuntimeException("索引錯誤");
        }else if(index>=size){
            throw new ArrayIndexOutOfBoundsException();
        }
        return (E)elementData[index];


    }

    /**
     *
     * @param index
     * @return 按照索引進行移除
     */
    public E remove(int index){
        if(index<0){
            throw new RuntimeException("索引錯誤");
        }else if(index>=size){
            throw new ArrayIndexOutOfBoundsException();
        }
        E old=get(index);
        System.arraycopy(elementData,index+1,elementData,index,(size-index-1));

        elementData[size--]=null;
        return old;
    }

    /**
     *
     * @param obj
     * @return 移除對象
     */
    public boolean remove(Object obj){
       int index= indexOf(obj);
        if(index>=0){
            System.arraycopy(elementData,index+1,elementData,index,(size-index-1));
            elementData[size--]=null;
            return true;
        }else{
            return false;
        }
    }


    /**
     * 轉換成數組
     * @return
     */
    public Object[] toArray(){

        return  Arrays.copyOf(elementData,size);
    }

    /**
     *
     * @return 打印輸出
     */
    public String toString(){
        StringBuilder sb=new StringBuilder();

        if(size==0){
            return "[]";
        }

        sb.append("[");
        for(int i=0;i<size;i++){

            sb.append(elementData[i]).append(",");
        }

        sb.replace(sb.length()-1,sb.length(),"]");
        return sb.toString();
    }

}

一.二 測試自定義 MyArrayList

package com.yjl.collection;

/**
 * package: com.yjl.collection
 * className: MyArrayListTest
 * Description: 請輸入相應的描述
 *
 * @author : yuezl
 * @Date :2020/6/10 14:21
 */
public class MyArrayListTest {
    public static void main(String[] args) {
        MyArrayList<Integer> mal=new MyArrayList<Integer>();

        System.out.println("長度:"+mal.size()+",是否爲空:"+mal.isEmpty());
        //添加元素
        mal.add(3);

        mal.add(4);
        //索引時添加
        mal.add(0,1);
        mal.add(1,2);
        //打印
        System.out.println("mal:"+mal.toString());

        //集合構建
        MyArrayList<Integer> mal2=new MyArrayList<Integer>(mal);

        System.out.println("mal2:"+mal2.toString());
        //添加所有
        mal2.addAll(mal);

        System.out.println("新的mal2:"+mal2.toString());

        //獲取值
       Integer val= mal2.get(3);
        System.out.println("輸出值爲:"+val);


        //索引長度構造
        MyArrayList<Integer> mal3=new MyArrayList<Integer>(3);

        mal3.add(1);

        mal3.add(2);

        mal3.add(3);
        System.out.println("長度1:"+mal3.toArray().length);
        mal3.add(4);

        System.out.println("長度2:"+mal3.toArray().length);

        //移除

        mal3.remove(1);
        System.out.println("長度3:"+mal3.toArray().length);

        mal3.remove(new Integer(3));
        System.out.println("長度4:"+mal3.toArray().length);

        //清除
        mal3.clear();

        System.out.println("長度:"+mal3.size()+",是否爲空:"+mal3.isEmpty());
    }
}

控制檯打印輸出:

有圖片

謝謝您的觀看,如果喜歡,請關注我,再次感謝 !!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章