arraylist 的扩容机制_每天都用ArrayList,你读过它的源码么?
作者:陌北有棵树,玩Java,架构师社区合伙人!
【一】关于扩容
如果没有指定初始容量,则设置为10
/** * Default initial capacity. */private static final int DEFAULT_CAPACITY = 10;
ArrayList的扩容比较简单,容量扩为之前的1.5倍/** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity */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);}
【二】关于拷贝
源码中用到的数组复制的两个方法分别是:System.arraycopy()和Arrays.copyOf()
一句话总结二者区别:Arrays.copyOf()可以看做是受限制的System.arraycopy()
Arrays.copyOf()是系统自己创建一个数组,再调用System.arraycopy()复制
public static T[] copyOf(U[] original, int newLength, Class extends T[]> newType) {@SuppressWarnings("unchecked") T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));return copy;}
System.arraycopy()需要传入一个目标数组作为参数,同时可以指定拷贝的起点和拷贝的长度
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos,int length);
各个参数的含义:
src - 源数组。
srcPos - 源数组中的起始位置。
dest - 目标数组。
destPos - 目标数据中的起始位置。
length - 要复制的数组元素的数量。
同时要注意的是,上述两个拷贝方法都是浅拷贝,关于深拷贝和浅拷贝,后续会做详细说明。
【三】关于Fail-Fast
Fail-Fast是非线程安全的集合,实现的一种错误机制。但不能百分百得到保证,只是尽最大努力抛出ConcurrentModificationException。
什么时候产生Fail-Fast
ArrayList中如何实现Fail-Fast
两个变量:modCount和expectedModCount
只要涉及到数组个数改变的方法,都会导致modCount的改变(add、remove、clear)
当发现expectedModCount和modCount不一致,就会抛出ConcurrentModificationException
所以,Iterator在遍历时,是不允许被迭代的对象被改变的
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException();}
如何避免Fail-Fast:用CopyOnWriteArrayList代替ArrayList
【四】关于ArrayList中删除元素
错误的删除方式一:for循环遍历删除
public void testRemove() { List integers = new ArrayList<>(5); integers.add(1); integers.add(2); integers.add(2); integers.add(4); integers.add(5);for (int i = 0; i if (integers.get(i) % 2 == 0) { integers.remove(i); } } System.out.println(integers);}
这段代码的输出是 [1,2,5]
因为在remove方法执行的时候,删除第一个“2”,会更新后面的索引值,数组变为[1,2,4,5],这样会导致第二个“2”不会被删除
错误的删除方式二:使用Iterator遍历,但仍用ArrayList的remove方法
public void testRemove(){ List strings = new ArrayList<>(); strings.add("a"); strings.add("b"); strings.add("c"); strings.add("d"); Iterator iterator = strings.iterator();while (iterator.hasNext()){ String next = iterator.next(); strings.remove(next); } System.out.println(strings);}
会抛出ConcurrentModificationException,参见上述的Fail-Fast机制
正确的删除方法:使用Iterator的remove方法
public static void main(String[] args) { List intList = new ArrayList(); Collections.addAll(intList, 1, 2, 3, 5, 6); Iterator it = intList.iterator();while(it.hasNext()) { Integer value = it.next();if(value == 3 || value == 5) { it.remove(); } } System.out.println(intList);}
长按订阅更多精彩▼
如有收获,点个在看,诚挚感谢
arraylist 的扩容机制_每天都用ArrayList,你读过它的源码么?相关推荐
- arraylist 的扩容机制_ArrayList详解
作者丨HUC南枫 来源丨甲哇技术栈(jiawa1024)ArrayList 的底层是数组队列,相当于动态数组.与 Java 中的数组相比,它的容量能动态增长.在添加大量元素前,应用程序可以使用ensu ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,多高(多线程与高并发)_Part9~整起(单双列集合们、ArrayList 的扩容机制、HashMap、ConcurrentHashMap )
再进入正文之前,先看看集合相关操作的时间复杂度: 本故事源自于~ 开唠: PART0: 为什么突然蹦出集合这个玩意,就是因为咱们基础那里学的"数组"不够用~: 数组一般用来保存一组 ...
- 各种风格简洁单页响应式html5模板_简洁 响应式 单页 跳转 设计 案例 源码340多套订餐企业模板高大尚响应式网站模板html5网页静态模板Bootstrap扁平化网站源码css3手机seo自适响
各种风格简洁单页响应式html5模板_简洁 响应式 单页 跳转 设计 案例 源码340多套订餐企业模板高大尚响应式网站模板html5网页静态模板Bootstrap扁平化网站源码css3手机seo自适响 ...
- arraylist扩容是创建新数组吗 java_arraylist扩容机制要怎么实现?arraylist怎么扩容...
ArrayList大家都知道了吧,这是一个动态数组.以java语言来说,数组是定长的,在被创建之后就不能被加长或缩短了,因此,了解它的扩容机制对使用它尤为重要.下面,我们就一起来看看它的扩容机制是怎么 ...
- 说一说 ArrayList 的扩容机制
ArrayList有三种方式来初始化,构造方法源码如下: /*** 默认初始容量大小*/private static final int DEFAULT_CAPACITY = 10;private s ...
- ArrayList的扩容机制
在Java中,ArrayList是一个使用非常频繁的集合类型,它的底层是Object数组,所以它拥有数组所拥有的特性,比如支持随机访问,所以查询效率高,但插入数据需要移动元素,所以效率低. 先来看看若 ...
- hashmap扩容机制_图文并茂:HashMap经典详解!
点击上方 Java后端,选择 设为星标 优质文章,及时送达 代码中的注解多看几遍,其中HashMap的扩容机制是要必懂知识!结合图片一起理解! 什么是 HashMap? HashMap 是基于哈希表的 ...
- 送分题,ArrayList 的扩容机制了解吗?
最近在准备暑期实习嘛,所以面经刷的比较多,前几天看见一位上岸的小伙伴写的面经,他说他在整理回顾知识点的时候(一般都用思维导图吧),会把知识点写成疑问句的形式,而不是陈述句,这样你在看到这句话的时候,会 ...
- hashmap扩容机制_图文并茂,HashMap经典详解!
Java面试笔试面经.Java技术每天学习一点 公众号Java面试 关注我不迷路 作者:feigeswjtu 来源:https://github.com/feigeswjtu/java-basics ...
最新文章
- 自动驾驶感知系统盘点
- 金融学习纲要与相关知识
- 转:canvas--放大镜效果
- 高性能JavaScript DOM编程
- python: numpy--函数 shape用法
- python functools
- iOS追踪设备和用户
- 在Ubuntu中为root用户启用界面登录
- java多线程(线程安全,线程同步)
- 易到起死回生的背后,谁在指点江山?
- kibana日志收集
- 人机大战简史:AI如何在20多年中一次次赶超人类
- remote debugger java,VS2015 远程调试:Remote Debugger
- 个人信息保护中,APP经常调用的Android类和方法
- [CSS]CSS 字体属性
- 移动端事件touchstart、touchmove、touchend详解
- 花呗接入央行征信系统!会影响贷款吗?
- 计算机显卡更新,电脑显卡升级,教您显卡怎么升级
- 2012-8-18可樂美文分享《遗留在时…
- 设计模式私家笔记——概述:设计模式是银弹吗?