手写一个简单版的ArrayList

简介: 手写一个简单版的ArrayList

一、设计一个简单的ArrayList[需要包含构造函数(有参和无参),add(obj),扩容 机制,remove方法]

  1.      import java.io.Serializable;

  2. public class MyArrayList  implements Serializable {
  3.    //第一次扩容的容量
  4.    public static final  int  DEFAULT_CAPACITY=10;
  5.    //用于初始化空的list
  6.    public static final  Object[] EMPTY_ELEMENT_DTAA={};
  7.    //实际存储的元素,transient:避免序列化的
  8.    transient Object[] elementData;
  9.    //实际存储list集合的大小
  10.    public int size=0;
  11.    //使用这个字段,来判断当前集合类是否被并发修改,即迭代器并发修改的fail-fast机制
  12.    private static int modCount=0;
  13.    //新版得jdk不会给创建一个对象
  14.    public MyArrayList(){
  15.         this.elementData=EMPTY_ELEMENT_DTAA;
  16.    }
  17.    public MyArrayList(int initialCapcity){
  18.         if(initialCapcity>0){
  19.             this.elementData=new Object[initialCapcity];
  20.         }else if(initialCapcity==0){
  21.             this.elementData=EMPTY_ELEMENT_DTAA;
  22.         }else{
  23.             throw new IllegalArgumentException("参数异常");
  24.         }
  25.    }
  26.    public boolean add(Object e){
  27.        //判断容量
  28.        ensureCapacityInternal(size+1);
  29.        //使用下标赋值
  30.        elementData[size++]=e;
  31.        return true;
  32.    }
  33.    private void ensureCapacityInternal(int minCapacity){
  34.           //用于并发判断
  35.           modCount++;
  36.           if(elementData==EMPTY_ELEMENT_DTAA){
  37.               minCapacity=Math.max(DEFAULT_CAPACITY,minCapacity);
  38.           }
  39.           //是否需要扩容,需要的最少容量大于现在的数组的容量,需要扩容
  40.           if(minCapacity-elementData.length>0){
  41.               int oldCapacity=elementData.length;
  42.               int newCapacity=oldCapacity+(oldCapacity>>1);
  43.               //如果新容量<最小容量,则将最新的容量赋值给新的容量
  44.               if(newCapacity-minCapacity<0){
  45.                   newCapacity=minCapacity;
  46.               }
  47.               //创建新数组
  48.               Object[] objects=new Object[newCapacity];
  49.               System.arraycopy(elementData,0,objects,0,elementData.length);
  50.               //修改引用
  51.               elementData=objects;
  52.           }

  53.    }
  54.    //通过下标获取元素
  55.    public Object get(int index){
  56.        rangeCheck(index);
  57.        return elementData[index];

  58.    }
  59.    private void rangeCheck( int  index){
  60.        if(index>size||size<0){
  61.            throw new IndexOutOfBoundsException("数组越界");
  62.        }
  63.    }
  64.    /**
  65.     * 判断对象所在的位置
  66.     */
  67.    public  int indexOf(Object o){
  68.        if(o==null){
  69.            for(int i=0;i<size;i++){
  70.                if(elementData[i]==null){
  71.                    return i;
  72.                }
  73.            }
  74.        }else{
  75.            for(int i=0;i<size;i++){
  76.                if(o.equals(elementData[i])){
  77.                    return i;
  78.                }
  79.            }
  80.        }
  81.        return -1;
  82.    }
  83.    //更新
  84.    public Object set(int index,Object obj){
  85.        rangeCheck(index);
  86.        Object oldValue=elementData[index];
  87.        elementData[index]=obj;
  88.        return oldValue;
  89.    }
  90.    //根据索引删除元素
  91.    public Object  remove(int index){
  92.        rangeCheck(index);
  93.        //用于并发判断
  94.        modCount++;
  95.        Object oldValue=elementData[index];
  96.        //计算要删除的位置后面有几个元素
  97.        int numMoved=size-index-1;
  98.        if(numMoved>0){
  99.            System.arraycopy(elementData,index+1,elementData,index,numMoved);
  100.        }
  101.        //将多出的位置为空,没有引用对象,垃圾收集器就可以回收,如果不置空,将会保存一个引用,可能会造成内存泄漏。
  102.        elementData[--size]=null;
  103.        return oldValue;
  104.    }
  105.    //获取数组实际大小
  106.    public  int  size(){
  107.        return this.size;
  108.    }
  109. }

测试下:

  1. public class Main {
  2.       public static void main(String[] args) {
  3.          MyArrayList  myArrayList=new MyArrayList();
  4.          for(int i=0;i<10;i++){
  5.              myArrayList.add("i"+i);
  6.              System.out.println(myArrayList.get(i));
  7.          }
  8.           System.out.println("----------------------------------");
  9.           Object remove = myArrayList.remove(0);
  10.           System.out.println(remove);
  11.       }
  12. }

明天关于Map的一些列的分享,敬请关注。

相关文章
|
4月前
|
Serverless
手写一个简单的HashMap
手写一个简单的HashMap
36 0
|
10月前
|
索引
源码分析系列教程(11) - 手写Map框架(基于LinkedList)
源码分析系列教程(11) - 手写Map框架(基于LinkedList)
28 0
|
4月前
|
存储 Java
ArrayList源码学习
深入学习ArrayList源码
ArrayList源码学习
|
10月前
|
存储 程序员
源码分析系列教程(10) - 手写LinkedList框架
源码分析系列教程(10) - 手写LinkedList框架
31 0
|
4月前
|
存储 安全 Java
基于ArrayList源码探讨如何使用ArrayList
基于ArrayList源码探讨如何使用ArrayList
|
4月前
|
索引
06 # 手写 map 方法
06 # 手写 map 方法
46 0
|
4月前
|
存储 Java 索引
深入学习Java集合之ArrayList的实现原理
深入学习Java集合之ArrayList的实现原理
39 0
|
存储 Java 开发者
|
存储 Java 程序员
ArrayList 的底层原理
ArrayList 是 Java 中常用的动态数组实现,它的底层是基于数组实现的。当创建一个 ArrayList 对象时,实际上是创建了一个 Object 类型的数组,初始容量为 10。当添加元素时,如果数组已满,ArrayList 会自动扩容,它会创建一个新的数组,并将原数组中的元素复制到新数组中。
934 0
ArrayList 的底层原理
|
存储 Java 容器
Java集合学习:ArrayList源码详解
Java集合学习:ArrayList源码详解
224 0