ArrayList面试系列

目录

  • ArrayList扩容机制为什么是1.5倍+1

ArrayList扩容机制为什么是1.5倍+1

这里是自己参考jdk [version "1.8.0_144"] ,也是目前正在使用的

  • 类实现
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  • 重要属性
/**
     * 默认初始容量
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * 用于空实例的共享空数组实例.
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
     * 用于默认大小的空实例的共享空数组实例,ArrayList的容量是此数组缓冲区的长度
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * 存储ArrayList元素的数组缓冲区.
     */
    transient Object[] elementData; // 非私有,以简化嵌套类访问

    /**
     * ArrayList的大小(它包含的元素数).
     */
    private int size;

    /**
     * 结构修改的次数
     */
    protected transient int modCount = 0;

Java中transient关键字的作用,简单地说,就是让某些被修饰的成员属性变量不被序列化

  • 1.size是数据的个数!elementData.length是elementData的c长度(包含被元素占用的空间和预留的空间)
public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

将现在的长度size加一后,传进ensureCapacityInternal里面

  • 2.DEFAULTCAPACITY_EMPTY_ELEMENTDATA是空数组,表示现在ArrayList是空的
private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

ensureCapacityInternal中首先是判断现在的ArrayList是不是空的,如果是空的,minCapacity就取默认的容量和传入的参数minCapacity中的大值
然后调用ensureExplicitCapacity方法

  • 3.modCount是fail fast机制,在jdk1.6之前都是有volatile来修饰的,尽可能的让并发访问非安全的集合对象时尽快的失败抛出异常,让程序员修改代码
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
}

在jdk1.7中去掉了volatile修饰,因为感觉没有必要为非线程安全集合浪费效率,在jdk1.5开始就提供了线程安全的集合类,在多线程环境下就应该使用线程安全的集合。
接着看,如果minCapacity的值大于add数据之前的大小,就调用grow方法,进行扩容,否则什么也不做

  • 4.注意:这里传过来的minCapcatiy的值是size+1,能够实现grow方法调用就肯定是(size+1)>elementData.length的情况,所以size就是初始最大容量或上一次扩容后达到的最大容量,所以才会进行扩容
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

newCapacity=oldCapacity+(oldCapacity>>1),这里就是扩容大小确定的地方,相当于新的最大容量是 size+1;size=1+0.5
相当于原来的1.5倍然后加1


  • 参考文章

  • 这里并没那么的太详细,如果有不明白的小伙伴可以在下方发私信,大家一起交流!

原文地址:https://www.cnblogs.com/ringbug/p/11343553.html

时间: 2024-11-08 22:49:15

ArrayList面试系列的相关文章

#面试系列 字符串处理算法

面试系列 字符串处理算法 最大子序列和 动态规划法 思路:顺序遍历,判断sum是否大于等于0 时间复杂度:O(n) 空间复杂度:O(1) #include <iostream> #include <limits.h> using namespace std; int getMaxSum(int *arr, int size) { int maxSum = INT_MIN; //负的无穷大 int sum = 0; int curstart = 0; int start = 0; i

【阿里面试系列】Java线程的应用及挑战

文章简介 上一篇文章[「阿里面试系列」搞懂并发编程,轻松应对80%的面试场景]我们了解了进程和线程的发展历史.线程的生命周期.线程的优势和使用场景,这一篇,我们从Java层面更进一步了解线程的使用.关注我的技术公众号[架构师修炼宝典]一周出产1-2篇技术文章.Q群725219329分享并发编程,分布式,微服务架构,性能优化,源码,设计模式,高并发,高可用,Spring,Netty,tomcat,JVM等技术视频. 内容导航 并发编程的挑战 线程在Java中的使用 并发编程的挑战 引入多线程的目的

计算机考研复试面试系列 计算机专业英语篇

计算机考研复试面试系列 计算机专业英语篇 在复习过程中,我用心查阅并整理了在考研复试面试中可能问到的大部分问题,并分点整理了答案,可以直接理解背诵并加上自己的语言润色!极力推荐打印下来看,效率更高! 此系列一共有8篇:编程语言篇|数据结构篇|操作系统篇|组成原理篇|计算机网络篇|数据库篇|软件工程篇|计算机专业英语篇(还未全部完成,敬请期待,你们的支持和关注是我最大的动力!) 个人整理,不可用于商业用途,转载请注明出处. 作者各个平台请搜索:程序员宝藏.快来探索属于你的宝藏吧! 需要pdf直接打

前端面试系列--前言篇

这个系列的文章将记录我准备春招的整个过程,我会将自己学习到的新知识记录在这个系列里 文章目录 前言说明 准备方向 目标 前言说明 ??作为半个科班出身学数学的应届生,在学习计算机的时候还是比较吃力的,从今年3月份开始接触前端,到现在也有8个月左右了.也许是初生牛犊不怕虎,我在5月份就各种投简历找实习,当时我甚至连前端是什么都不知道,只学过html和css,还只是通过看<Head First Html与Css>来了解关于写页面的知识的,这本书是2013年出版的,距离现在已经有5年的时间了,现在看

(第一期)大厂面试系列_ArrayList 公众号java源码栈

目录 1.ArrayList是什么?可以用来干嘛?2.ArrayList数组的初始大小长度是怎样的?长度不够时怎么办.3.为什么说数组增删速度慢,增删时ArrayList是怎么实现的?4.ArrayList(int initialCapacity)是初始化数组大小吗?5.ArrayList是线程安全的么?怎样线程安全的使用ArrayList呢?6.ArrayList适合用来做队列么?7.removeAll, retrain, clean三个方法有什么不同?8.ArrayList的浅复制和深复制有

数据库面试系列之五:mysql的存储引擎

mysql的默认存储引擎是innoDB,是唯一一个支持事务和支持外键的存储引擎, 可以通过:show variables like 'default_storage_engine';查看当前数据库到默认引擎.命令:show engines和show variables like 'have%'可以列出当前数据库所支持的存储引擎. mysql的主要存储引擎有:innoDB,myISAM,merge,memory myISAM:不支持事务,不支持外键,访问速度尤其快,如果以查询和插入为主的表可以设置

数据库面试系列之六:会写基本的sql语句

面试让写的sql语句涉及到order by ,group by, having ,like ,limit  等 order by 排序 asc生序,desc降序 group by 分组,having用于分组筛选 like用于模糊匹配查询 limit控制返回的结果条数,以及从第几条返回 select sid,sum(score) as 总分数 where sid>1004 group by sid having 总分数>60 order by 总分数 desc; select * from st

数据库面试系列大纲

数据库面试经常被问到的考点: 1.内连接和外连接,左外连接和右外连接,全外连接 2.视图是什么,视图的优点 3.索引的优点,建立索引的规则有哪些? 4.写sql语句:涉及到order by ,group by, having ,like ,limit  等 5.什么是慢查询?如何优化慢查询? 6.mysql性能优化 7.mysql的存储引擎都有哪些?这些存储引擎有什么区别? 后面会针对每个点写单独的博客...

面试系列11 缓存是如何使用

一个一个来看 (1)在项目中缓存是如何使用的? 这个,你结合你自己项目的业务来,你如果用了那恭喜你,你如果没用那不好意思,你硬加也得加一个场景吧 (2)为啥在项目里要用缓存呢? 用缓存,主要是俩用途,高性能和高并发 1)高性能 假设这么个场景,你有个操作,一个请求过来,吭哧吭哧你各种乱七八糟操作mysql,半天查出来一个结果,耗时600ms.但是这个结果可能接下来几个小时都不会变了,或者变了也可以不用立即反馈给用户.那么此时咋办? 缓存啊,折腾600ms查出来的结果,扔缓存里,一个key对应一个