学习ArrayList的扩容机制
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private int size;
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private static final int DEFAULT_CAPACITY = 10;
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
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);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE)?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
--拓展--
因为ArrayList底层是一个Object数组,在多线程环境中可以会出现并发争抢的问题,
java提供三种解决方案:
1.new Vector jdk1.0就出现的类
public void add(E e) {
int i = cursor;
synchronized (Vector.this) {
checkForComodification();
Vector.this.add(i, e);
expectedModCount = modCount;
}
cursor = i + 1;
lastRet = -1;
}
加了synchronized保证add方法线程安全性,但是并发性急剧下降,所以在jdk1.2中才
会出现ArrayList这个类。
2.Collections.SynchronizedList(new ArrayList());
public boolean add(E e) {
synchronized (mutex) {return c.add(e);}
}
3.new CopyOnWriteArrayList();
private transient volatile Object[] array;
使用volatile关键字,保证array数组可见性,禁止指令重排;
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
add方法添加ReentrantLock 可重入锁(递归锁),保证add方法在多线程环境中程序执行
的安全性。
学习ArrayList的扩容机制的更多相关文章
- ArrayList的扩容机制
一.ArrayList的扩容机制 1.扩容的计算方式是向右位移,即:newSize = this.size + (this.size>>1).向右位移,只有在当前值为偶数时,才是除以2:奇 ...
- 关于ArrayList的扩容机制
关于ArrayList的扩容机制 ArrayList作为List接口常用的一个实现类,其底层数据接口由数组实现,可以保证O(1) 复杂度的随机查找, 在增删效率上不如LinkedList,但是在查询效 ...
- 浅谈 ArrayList 及其扩容机制
浅谈ArrayList ArrayList类又称动态数组,同时实现了Collection和List接口,其内部数据结构由数组实现,因此可对容器内元素实现快速随机访问.但因为ArrayList中插入或删 ...
- 【数组】- ArrayList自动扩容机制
不同的JDK版本的扩容机制可能有差异 实验环境:JDK1.8 扩容机制: 当向ArrayList中添加元素的时候,ArrayList如果要满足新元素的存储超过ArrayList存储新元素前的存储能力, ...
- Java ArrayList自动扩容机制
动态扩容 1.add(E e)方法中 ① ensureCapacityInternal(size+1),确保内部容量,size是添加前数组内元素的数量 ② elementData[size++] ...
- ArrayList动态扩容机制
初始化:有三种方式 1.默认的构造器,将会以默认的大小来初始化内部的数组:public ArrayList(); 2.用一个ICollection对象来构造,并将该集合的元素添加到ArrayList: ...
- 小白也能看懂的ArrayList的扩容机制
来,话不多说进入正题!我们下面用最简单的代码创建ArrayList并添加11个元素,并 一 一 讲解底层源码:在说之前,给大家先普及一些小知识: >ArrayList底层是用数组来实现的 > ...
- 送分题,ArrayList 的扩容机制了解吗?
1. ArrayList 了解过吗?它是啥?有啥用? 众所周知,Java 集合框架拥有两大接口 Collection 和 Map,其中,Collection 麾下三生子 List.Set 和 Queu ...
- ArrayList源码解析(二)自动扩容机制与add操作
本篇主要分析ArrayList的自动扩容机制,add和remove的相关方法. 作为一个list,add和remove操作自然是必须的. 前面说过,ArrayList底层是使用Object数组实现的. ...
随机推荐
- 关于Objective C的私有函数
(1)很多从其他语言(例如C++)转到objective c的初学者,往往会问到一个问题,如何定义类的私有函数?这里的“私有函数”指的是,某个函数只能在类的内部使用,不能在类的外部,或者派生类内部使用 ...
- FreeRTOS列表和列表项
FreeRTOS中的列表和列表项类似于数据结构中的链表和节点: 相关的文件是list.c和list.h两个文件: List_t列表结构体 具体定义如下: /* * Definition of the ...
- Python 编码encode()、 解码decode()问题
乱码这种东西,时不时出现.本来开开心心想着我要学习啦,然后兴高采烈打开了比火星文还火星文的字符-- 没事,我可以搞定这堆鬼画符. 先来讲一下为什么有乱码这种东西的存在 故事是这样滴: 字符串是Pyth ...
- evpp http put问题
https://blog.csdn.net/yuzuyi2006/article/details/82112664 最近做了一个项目需要实现web服务,使用了evpp.但是在用的过程中碰到了http ...
- Nginx的简单了解与使用
一.产生背景 我们日常生活中经常遇到的问题 这是几年前的12306,现在的12306基本上不会出现这样的问题了 上述场景产生的主要 2 大原因:1.巨大流量2.单台服务器资源和能力有限在海量并发的环境 ...
- goroutine 修改全局变量无效问题
原文:https://studygolang.com/topics/7050 go修改全局变量的问题 测试 goroutine 修改全局变量,有x y 两个全局函数,分别在两个 goroutine f ...
- Lua 学习之基础篇二<Lua 数据类型以及函数库 汇总>
引言 前面讲了运算符,这里主要对Lua的数据处理相关的数据类型和函数库进行总结归纳,后面会再接着单独分开讲解具体使用. 首先因为Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值. 值可以存储 ...
- Oracle不足补零函数
,') from dual ,') from dual ,') from dual ,') from dual ,') from dual
- mysql json数据类型
概述 Mysql从5.7.8版本开始支持JSON字段,可以高效的处理JSON文档.相比字符串字段,JSON字段有下面的几处优势: 自动的校验JSON格式,无效的文档会产生错误 优化的存储格式(结构化的 ...
- csv测试类。用起来,就是那么简单。每个单元格都是以逗号分隔
package com.hyxt.wxpay.util; import java.io.File; import java.util.ArrayList; import java.util.List; ...