手写ArrayList的实现、原理及优化

一、前言

        对于arraylist集合,其是List接口下的一种数据存储结构,底层由数组组成。本身特点为:查找快,增删慢(原因:因为底层是数组,而数组是需要一个连续的空间,每次的增删就相当于数组的移动和复制,从而效率大大降低。但是在查询上,效率极高。)

二、核心

     1. 在翻阅jdk源码之后,其大致可以总结为:

  • 进行add方法添加之后,默认值首先为0,其次有一个判断,从而使默认值为10;
  • 扩容机制为1.5倍的扩容,采用的是位运算(位运算在java中的效率高);
  • 核心代码为
System.arraycopy (objects,0,temp,0,objects.length);

     其作用为数组的复制,参数依次为:源对象,源对象起始位置,目标对象,目标对象起始位置,拷贝元素个数。

     2. ArrayList非线程安全,如果多个线程同时对同一个arraylist更改数据的话,会导致数据不一致或者数据污染,如果出现线程不安全操作的时候,arraylist尽可能的抛出concurrentModifycationException防止数据异常。如果想保证线程安全,可以使用vector...

三、手写arraylist的简单实现

package Arraylist;

import sun.applet.Main;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Objects;

public class MyArraylist {

    //数组容器,jdk中默认大小为10
    private Object[] objects = new Object[3];
    //初始大小
    private int size = 0;

    //数组的添加方法
    public void add(Object obj){
        //判断是否索引大于容器容量,如果大于,则扩容(新建数组)arraylist支持的是1.5倍扩容
        if(size >= objects.length){
            //jdk中采用的是位运算,区别在于位运算效率更高
            Object[] temp = new Object[size*3/2 + 1];
            //核心方法,相当于数组的复制
            System.arraycopy (objects,0,temp,0,objects.length);
            objects = temp;
        }
        objects[size] = obj;
        size++;
    }
    //集合的长度
    public int length(){
        return size;
    }
    //集合指定元素的赋值
    public void set(int index,Object obj) throws Exception {
        if(index <= size && index >= 0){
                objects[index] = obj;
        }else{
            throw new Exception ("数组下标越界");
        }
    }
    //获取指定下标的元素
    public Object getValue(int index) throws Exception {
        if(index > size || index < 0){
            throw new Exception ("数组下标越界");
        }
        return objects[index];
    }
    //删除指定下标的元素
    public Object remove(int index) throws Exception {
        if(index > size || index < 0){
            throw new Exception ("数组下标越界");
        }
        //要返回的元素
        Object obj = objects[index];
        //从删除元素的后一个位置开始复制,复制newIndex个(相当于数组的自我复制)
        int newIndex = objects.length-1-index;
        System.arraycopy (objects,index+1,objects,index,newIndex);
        //复制完后,长度要减一
        size--;
        return obj;
    }
    //清空集合
    public void clear(){
        size = 0;
        objects = new Object[3];
    }

    //测试方法
    public static void main(String[] args) throws Exception {
        MyArraylist ma = new MyArraylist ();
        ma.add ("1");
        ma.add ("2");
        ma.add ("3");
        ma.add ("4");
//        ma.clear ();
//        System.out.println (ma.size);
//        System.out.println (ma.remove (2));
        for (int i = 0;i < ma.length ();i++){
            Object obj = ma.getValue (i);
            System.out.println (obj);
        }

    }
}

四、优化

  • 如果在初始化的时候知道ArrayList的初始容量,请一开始就指定容量ArrayList<String> list = new ArrayList<String>(20);
  • 如果一开始不知道容量,中途才得知,请调用list.ensureCapacity(20);来扩充容量;
  • 如果数据已经添加完毕,但仍需要保存在内存中一段时间,请调用list.trimToSize()将容器最小化到存储元素容量,进而消除这些存储空间浪费。

猜你喜欢

转载自blog.csdn.net/zz18435842675/article/details/81911862