ArrayList的add(E e)方法与扩容
ArrayList是Java开发中经常用到的集合类,它是List接口的实现类,具有很高的查询性能,但不是线程安全的。本文主要讲述了ArrayList的add(E e)方法及该方法中涉及到的容量扩容技术。
- 本文大纲
1.ArrayList底层数据结构
2.add(E e)方法流程概览
3.add(E e)方法与扩容源码分析
说明:本文对ArrayList的源码分析是基于JDK8。
- 正文
1.ArrayList底层数据结构
ArrayList的底层数据结构为一个Object数组,对应到源码中是:
transient Object[] elementData; // non-private to simplify nested class access
2.add(E e)方法流程概览
add(E e)方法的大致流程:

3.add(E e)方法与扩容源码分析
接着再看一下源码:
public boolean add(E e) {
// 确保数组有足够的空间来存储对象e
ensureCapacityInternal(size + 1); // Increments modCount!!
// 将对象e存放到数组的末尾
elementData[size++] = e;
return true;
}
ensureCapacityInternal方法主要是确保elementData数组有足够的空间来存储待添加的元素:
// 参数minCapacity是add(E e)方法中调用ensureCapacityInternal方法时传入的size + 1的值
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
参数minCapacity是为了存放这个元素elementData数组所需要的最小的大小。比如,现在一个数组中存放了10个元素,再次向该数组存放一个元素时,那么这个minCapacity的值就是size + 1,即10 + 1 = 11。
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
// 存放新元素所需的最小容量大于elementData数组的长度
grow(minCapacity);
}
如果存放新元素所需的最小容量大于elementData数组的长度,即当前数组的容量不足,不能再存放新的元素,那么将基于elementData数组进行扩容。
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); // 计算新数组的容量,新数组的容量为原数组容量的1.5倍数。>>是移位运算符,oldCapacity >> 1表示oldCapacity除以2
if (newCapacity - minCapacity < 0) // 针对当创建的ArrayList的容量大小为1时能够进行扩容(下面将详细分析)
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); // 进行数组拷贝,并将新产生的数组赋值给elementData
}
当我们在new ArrayList的时候,如果指定ArrayList的容量大小为1(比如,new ArrayList<>(1)),再进行add(E e)操作,在执行代码int newCapacity = oldCapacity + (oldCapacity >> 1)时,newCapacity的值为1,newCapacity与oldCapacity的值都为1,这样其实并没有进行扩容。if (newCapacity - minCapacity < 0)就是为避免这种情况,当newCapacity(此例中为1)的值小于minCapacity(此例中为2)时,就把minCapacity的值赋给newCapacity。
ArrayList的add(E e)方法与扩容的更多相关文章
- ArrayList的add方法实现
ArrayList的底层是由数组实现,所以所有的操作都是围绕数组展开,要想理解add方法,就得先了解数组的增加,所以我们先实现一个数组的add,数组的添加可以从尾部增加或者其他位置插入, 如果在数组的 ...
- Java集合详解1:一文读懂ArrayList,Vector与Stack使用方法和实现原理
本文非常详尽地介绍了Java中的三个集合类 ArrayList,Vector与Stack <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整 ...
- ArrayList和HashSet的Contains()方法(转)
来源: ArrayList和HashSet的Contains()方法 笔试题: package com.champion.test.exam; import java.util.ArrayList; ...
- Java-集合(没做出来)第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列。 例如: List list = new ArrayList(); list.add(“Hello”); list.add(“World”); list.add(“Learn”); //此时list 为Hello World Learn reverseL
没做出来 第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列. 例如: List list = new ArrayList(); list.a ...
- java中把list列表转为arrayList以及arraylist数组截取的简单方法
java中把list列表转为arrayList以及arraylist数组截取的简单方法 package xiaobai; import java.util.ArrayList; import java ...
- Java学习笔记27(集合框架一:ArrayList回顾、Collection接口方法)
集合:集合是java中提供的一种容器,可以用来存储多个数据 集合和数组的区别: 1.数组的长度是固定的,集合的长度是可变的 2.集合中存储的元素必须是引用类型数据 对ArrayList集合的回顾 示例 ...
- Java进阶(二十四)Java List集合add与set方法原理简介
Java List集合add与set方法原理简介 add方法 add方法用于向集合列表中添加对象. 语法1 用于在列表的尾部插入指定元素.如果List集合对象由于调用add方法而发生更改,则返回 tr ...
- java学习笔记20(Arraylist复习,Collection接口方法,迭代器,增强型for循环)
集合:集合是Java提供的一种容器,可以用来存储多个数据: 集合与数组的区别:集合的长度是可变的,数组的长度是固定的 集合中存储的数据必须是引用类型数据: ArrayList回顾: public cl ...
- C#集合中的Add与AddRange方法
C#.NET的集合主要位于System.Collections和System.Collections.Generic(泛型)这两个namespace中. 1.System.Collections 比如 ...
随机推荐
- nginx 反向代理,支持跨域,前后分离
前端开发往往涉及到跨域问题,其中解决方案很多: 1.jsonp 需要目标服务器配合一个callback函数. 2.window.name+iframe 需要目标服务器响应window.name. 3. ...
- PermutationTwo
Description: Given a collection of numbers that might contain duplicates, return all possible unique ...
- 获取linux帮助命令
命令的分类 linux的命令分为内部命令和外部命令. 内部命令指的是shell程序自带的命令,是shell程序的一部分,这些命令由shell程序识别并在shell程序内部完成运行,通常在linux系 ...
- tomcat 构建问题记录
mvng构建程序包com.sun.image.codec.jpeg不存在------->缺少serlet的jar包 MasterSlaveRoutingDataSource不是抽象的, 并且未覆 ...
- 进阶-MongoDB 知识梳理
MongoDB 一.MongoDB简介 MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种.它在许多场景下可用于替代传统的关系型数据库或键/值存储方式.Mo ...
- vh、vw、vmin、vmax 知多少
介绍一些 CSS3 新增的单位,平时可能用的比较少,但是由于单位的特性,在一些特殊场合会有妙用. vw and vh 1vw 等于1/100的视口宽度 (Viewport Width) 1vh 等于1 ...
- 高质量的内容是SEO的关键
内容是最有效的SEO策略,但也是最难执行的 正确的目录对SEO(搜索引擎优化:search engine optimization)关乎重大.根据Ascend2在2014年4月对全球营销专业人士做的调 ...
- 聊聊 Spring Boot 2.x 那些事儿
本文目录: 即将的 Spring 2.0 - Spring 2.0 是什么 - 开发环境和 IDE - 使用 Spring Initializr 快速入门 Starter 组件 - Web:REST ...
- JSONUtils.toJSONString的一个坑
JSONUtils.toJSONString(null); //返回一个为"null"的字符串 这样会导致一个结果就是StringUtils.isBlank判断后,会为false ...
- python实现邮件的发送
一.163邮箱设置 进入163邮箱,点击设置中的pop3/smtp/imap 开启smtp服务,如果没有开启,点击设置,手机号验证后勾选开启即可,开启后图如下: 主要用到的就是smtp服务器:smtp ...