每天一道面试题(13)----ArrayList内部用什么实现的?

ArrayList是Java中常用的动态数组,其内部通过Object[]数组实现。构造函数根据传入参数决定数组大小,若不指定,默认使用EmptyArray.OBJECT。添加元素时,当数组满时会扩容,通常容量增加为原来的1.5倍。删除元素后,数组不会自动缩小,可能导致空间浪费。此文章深入探讨了ArrayList的内部实现和内存管理策略。
摘要由CSDN通过智能技术生成

ArrayList内部用什么实现的?

回答这样的问题,不要只回答皮毛,可以再介绍一下ArrayList内部是如何实现数组的增删的,因为数组在创建的时候长度是固定的,那么就有个问题我们往ArrayList中不断地添加对象,它是如何管理这些数组呢?

ArrayList内部是用Object[]实现的。

一、构造函数

  1. 空参构造
    public ArrayList(){
        array = EmptyArray.OBJECT;
    
    }

    array是一个Object[]类型。当我们new一个空参构造时系统调用了EmptyArray.OBJECT属性,EmptyArray仅仅是一个系统的类库,该类源码如下: 

    public final class EmptyArray{
        private EmptyArray(){}
    
        public static final boolean[] BOOLEAN = new boolean[0];
        public static final byte[] BYTE = new byte[0];
        public static final char[] CHAR = new char[0];
        public static final double[] DOUBLE = new double[0];
        public static final int[] INT = new int[0];
    
        public static final Class<?>[] CLASS = new Class[0];
        public static final Object[] OBJECT = new Object[0];
        public static final String[] STRING = new String[0];
        public static final Throwable[] THROWABLE = new Throwable[0];
        public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0];
    
    }

    也就是说我们new一个空参ArrayList的时候,系统内部使用了一个new Object[0]数组。

  2. 含参构造 1

    /**
    Constructs a new instance of {@code ArrayList} with the specified
    initial capacity.
    
    @param capacity
            the initial capacity of the {@code ArrayList}.
    
    */
    public ArrayList (int capacity){
        if(capacity < 0){
            throw new IllegalArgumentException("capacity < 0: " + capacity);
        }
    
        array = (capacity == 0 ? EmptyArray.OBJECT : new Object[capacity]);
    
    
    }

     该构造函数传入一个int值,该值作为数组的长度值。如果该值小于0,则抛出一个运行时异常。如果等于0,则使用一个空数组,如果大于0,则创建一个长度为该值的新数组。

  3.  

    含参构造2

     

    /**
     * Constructs a new instance of {@code ArrayList} containing the elements of
     * the specified collection.
     *
     * @param collection
     * the collection of elements to add.
     */
     public ArrayList(Collection<? extends E> collection) {
         if (collection == null) {
             throw new NullPointerException("collection == null");
         }
    
         Object[] a = collection.toArray();
         if (a.getClass() != Object[].class) {
         Object[] newArray = new Object[a.length];
         System.arraycopy(a, 0, newArray, 0, a.length);
         a = newArray;
         }
    
         array = a;
         size = a.length;
     }

    如果调用构造函数的时候传入一个Collection的子类,那么先判断该集合是否为null,为null则抛出空指针异常。如果不是则将该集合转换为数组a,然后将该数组赋值为成员变量array,将该数组的长度作为成员变量size。这里面它先判断a.getClass是否等于Object[].class,其实一般都是相等的,toArray方法是Collection接口定义的,因此其所有的子类都有这样的方法,list集合的toArray和Set集合的toArray返回的都是Object []数组。

     

     

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值